home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / PROGTOOL / MBLIB10.ZIP;1 / MB_LIB.DOC < prev    next >
Encoding:
Text File  |  1993-03-07  |  119.4 KB  |  3,157 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.             =============================================================
  15.  
  16.                                      MB_lib V1.0
  17.  
  18.                 Hudson and Opus message base interface library for C
  19.  
  20.                           (c) F.W. van Wensveen 1992, 1993
  21.  
  22.                                  All Rights Reserved
  23.  
  24.             =============================================================
  25.  
  26.  
  27.                 The author of this software can be reached via E-mail
  28.                   as Frank Van.wensveen at the following addresses:
  29.  
  30.                                 2:285/504@fidonet.org
  31.                                27:1331/703@signet.org
  32.                                 310/902 GT Power net
  33.                    frank.van.wensveen@p0.f504.n285.z2.fidonet.org
  34.  
  35.                                  BBS: +31-10-4717477
  36.                  (V21, V22, V22b, V23, V32b, V42b, MNP2..5 - 24h/day
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.                     Abstract
  51.  
  52.                     MB_lib is a message library for use with C (calling the
  53.                     routines  from  other  languages  is,  of  course, also
  54.                     possible). It provides a full set of services needed to
  55.                     interface your applications with both Hudson and *.MSG-
  56.                     style message bases quite easily.
  57.  
  58.                     This document only contains flat ASCII.
  59.  
  60.  
  61.  
  62.  
  63.           ============================================================
  64.           1. INTRODUCTION
  65.           ============================================================
  66.  
  67.           Why MB_lib?
  68.           -----------
  69.  
  70.           One of  the most important features BBSes and mail systems is the
  71.           ability to handle electronic mail. This  enables people  from all
  72.           over the world to communicate with each other against hardly more
  73.           than the cost of (usually) local phone calls. Initially, messages
  74.           were stored  by the  BBS and/or mailer software in separate files
  75.           for each message (the well-known *.MSG files).
  76.           Since this proved a very inefficient way of using disk space, the
  77.           Hudson message  base was  developed. This message base stores all
  78.           messages in only five files, one of which contains the total text
  79.           of all messages in the system, while the other files act as index
  80.           files. This  system uses  the available  more efficiently. Today,
  81.           the  Hudson  message  base  is  used by many popular BBS and mail
  82.           programs like  Remote  Access,  SuperBBS,  Quick  BBS, FrontDoor,
  83.           TosScan, Fmail, and lots, lots more.
  84.  
  85.           The Hudson  message base  however has the disadvantage that it is
  86.           quite complicated to access when  compared  with  a  simple *.MSG
  87.           file. Therefore,  programmers have had more difficulty developing
  88.           software to interface with  the Hudson  message base,  since they
  89.           would  have  to  write  their  own,  often complicated, interface
  90.           routines  first,  before  getting  down  to  the  meat  of  their
  91.           applications.
  92.           This library  intends to  remedy that  by providing a full set of
  93.           functions that allow you to interface with both  Hudson and *.MSG
  94.           message bases  in a  very simple  way. If  you're a C programmer,
  95.           this is what you've been waiting for.
  96.           MB_lib is a library intended for use with C. It was written using
  97.           Borland Turbo  C 2.01.  and Turbo Assembler 1.5. It may also work
  98.           with other compilers than Borland's. Of course you  can also call
  99.           the functions  from other  languages like  Assembly, provided you
  100.           know how. I intend to  release  a  version  for  Borland  C++ for
  101.           Windows, but  at the time this document was written, this version
  102.           isn't finished yet. As far as  I know  this is  the first library
  103.           offering these services to the C community.
  104.  
  105.  
  106.           A WORD TO THOSE WHO'D RATHER USE PASCAL
  107.           ---------------------------------------
  108.  
  109.           For those  with Pascal  experience the story might begin to sound
  110.           familiar. For Turbo Pascal there already  is a  unit with message
  111.           base  routines  available.  This  is MSGBASE by Richard Faasen of
  112.           Sliedrecht,  The  Netherlands,  SysOp  of  InFase  BBS (+31-1840-
  113.           21818). So  if you're  a Pascal programmer, you can either switch
  114.           to C (why not?) or contact Richard.
  115.           This library is based upon Richards original Pascal  source code.
  116.           (See also the credits at the end of this document.)
  117.  
  118.  
  119.  
  120.  
  121.  
  122.                                                 2
  123.  
  124.  
  125.  
  126.  
  127.           FEATURES
  128.           --------
  129.  
  130.           The  most  important  features  of  MB_lib  include  (but are not
  131.           limited to):
  132.           *    All you need to  read, write,  search for  or kill messages.
  133.                Writing a new message is as easy as msg_write_new ()!
  134.           *    Dynamic  use  of  memory.  Message text can have *any* size,
  135.                the only restriction being  actual  memory  limits.  Text is
  136.                manipulated using a 'text handle'.
  137.           *    Flexible,  well-behaved,  and  stable.  With flexible I mean
  138.                that MB_lib won't get in the way of whatever you're doing in
  139.                your  applications   (you  can,  for  example,  call  MB_lib
  140.                routines when in  graphics  mode  without  problems). MB_lib
  141.                interfaces with your operating system in a decent way.
  142.           *    Powerful yet flexible error trapping and -handling.
  143.           *    Fully supports  the Remote  Access 1.11 message base locking
  144.                technique. This means  you  can  write  programs  suited for
  145.                multi-tasking environments,  as required by applications for
  146.                Remote Access on multi-line systems.
  147.           *    Written with portability in mind. I haven't tried it as yet,
  148.                but porting  MB_lib to other platforms than MS-DOS should be
  149.                relatively easy.  The only  system-dependent code  is in the
  150.                locking mechanism, which other OSes might not need.
  151.           *    No-nonsense programming  style. No  effort has  been made to
  152.                dress up the software or to provide flashy effects. Instead,
  153.                the code is flexible and well-behaved enough so that you may
  154.                do  that  yourself  if  you  wish.  MB_lib  concentrates  on
  155.                providing  fast,   stable  and  efficient  services  without
  156.                unwanted overhead (Unix people will get the idea).
  157.  
  158.  
  159.           FILES IN THE PACKAGE
  160.           --------------------
  161.  
  162.           The distribution package of  MB_lib should  contain the following
  163.           files:
  164.  
  165.           MB_LIB.DOC     The file you are currently reading
  166.           MB_LIB.H       The header file for MB_lib
  167.           MB_LIBT.LIB    Message base library file, Tiny model
  168.           MB_LIBS.LIB    Message base library file, Small model
  169.           MB_LIBC.LIB    Message base library file, Compact model
  170.           MB_LIBM.LIB    Message base library file, Medium model
  171.           MB_LIBL.LIB    Message base library file, Large model
  172.           MB_LIBH.LIB    Message base library file, Huge model
  173.           *.C            Example programs.  Look here  for tips & tricks on
  174.                          how to use the library functions in your programs.
  175.           RALCK003.DOC   The Remote Access Locking Specification version 3,
  176.                          contains details on message base locking.
  177.  
  178.           If you receive a version with any of these files missing, you can
  179.           obtain a complete and  uncorrupted  version  of  MB_lib  from the
  180.           author.
  181.  
  182.  
  183.  
  184.  
  185.  
  186.                                                 3
  187.  
  188.  
  189.  
  190.  
  191.           ABOUT THIS MANUAL
  192.           -----------------
  193.  
  194.           Like the  code, this  manual is very straightforward. It provides
  195.           brief insights on how  the Hudson  message base  stores messages,
  196.           how  MB_lib  handles  things,  and  than proceeds to describe the
  197.           library functions. In other words,  this  document  is  meant for
  198.           people familiar  with C.  It is  beyond the scope of this text to
  199.           explain how functions are called  or  how  pointers  are  used to
  200.           handle data.
  201.           The function  descriptions should look familiar to anyone who has
  202.           ever seen a C reference guide  or used  a man  command on  a Unix
  203.           system. Basic  knowledge about  echomail is  assumed. It wouldn't
  204.           hurt to be familiar with FTS-0001, either.
  205.           Sometimes examples are given in the  reference section. Sometimes
  206.           these  examples  are  complete  programs, sometimes not. The only
  207.           purpose of these examples is to illustrate how a certain function
  208.           works, so do not regard them as complete and functional programs.
  209.           Example source code is included in  the distribution  package. It
  210.           might really be a good idea to have a look at it.
  211.  
  212.  
  213.           CREDITS
  214.           -------
  215.  
  216.           Special thanks to the following people:
  217.  
  218.           *    Richard  Faasen,  who  wrote  the  original  Pascal  version
  219.                (MsgBase 1.0) and gave me the Pascal source to have  a go at
  220.                it in  C. Never mind the fact that he tried to convert me to
  221.                C++ just before the beta version was finished. <grin>
  222.           *    The beta team: Feico de Boer, Olaf Westrik, Arnoud de Jonge,
  223.                Richard Faasen,  plus lots  of people  who made suggestions,
  224.                offered advice, or just gave moral support.
  225.           *    John Lots for many tips and pieces of advice that (sometimes
  226.                unintended and without his knowledge) finally ended up here.
  227.           *    Brian Pirie  of Ottawa,  Ontario, who  knows how  to write a
  228.                hashing algorithm.
  229.           *    Everyone who replied to  my questions  in the  FIDOnet C and
  230.                Assembly conferences.
  231.  
  232.           Thank you, guys! You were all most helpful.
  233.  
  234.  
  235.           DISTRIBUTION, LICENCING AND LEGALESE
  236.           ------------------------------------
  237.  
  238.           The latest  version of  MB_lib is  always available on my BBS, or
  239.           you can request it from one of my E-mail addresses. See the front
  240.           page  of  this  document  for  details. For support, bug reports,
  241.           etc., you can also contact me at the adresses on the front page.
  242.           If you've written programs using this library, I'd really like to
  243.           see them,  and, if  you want  me to,  I'll be happy to comment on
  244.           them, and distribute the via my BBS.
  245.  
  246.           You may (and in fact, are  encourage to)  copy this  software and
  247.           distribute those copies. However, YOU MAY NOT:
  248.  
  249.  
  250.                                                 4
  251.  
  252.  
  253.  
  254.  
  255.           -    Alter or  remove any  portion of the package, including this
  256.                document, in any way.
  257.           -    Distribute it  on  a  commercial  basis.  You  may, however,
  258.                charge a  nominal fee not to exceed the cost of floppy disks
  259.                and mailing costs.
  260.           -    Distribute  program's  you've   written   and   compiled  an
  261.                unregistered version of MB_lib.
  262.  
  263.           Disclaimer:  The  author  of  this  software  does not accept any
  264.           responsibility for any damage, direct or indirect, including, but
  265.           not limited to, lost profits, lost savings, or loss or corruption
  266.           of data, resulting from the use of, or the inability to use, this
  267.           software. 
  268.           The software  is provided 'as is', without any guarantee whatsoe-
  269.           ver. If it works for you, fine. If it does  not, too  bad. If you
  270.           try this  program and your system goes to pieces, I'm not obliged
  271.           to provide you with a tube of glue. It is the users responsibili-
  272.           ty  to  make  backups  of  important data, to carefully check out
  273.           untested software, and to take precautions in general.  So if you
  274.           like to live dangerously, on your own head be it.
  275.  
  276.           The author  retains the copyright to this software. This software
  277.           is NOT in the public domain. Source code  is not  available, and,
  278.           by previous agreement to other parties, it won't become available
  279.           in the future.
  280.  
  281.           As to licencing: THIS IS NOT  FREE  SOFTWARE!  I  know,  for many
  282.           people this part is a giggle, but bear with me for a moment.
  283.           You  may  try  this  software  for  30 days. If you decide not to
  284.           continue using it after  the trial  period of  30 days,  you must
  285.           stop using  it, and  you must destroy (== delete) all executables
  286.           containing linked code from MB_lib.
  287.           If you decide that the stuff  is worth  the disk  space, you must
  288.           register  MB_lib.  See  the  file  REGISTER.TXT, included in this
  289.           package, for conditions and full details on how to register.
  290.  
  291.  
  292.           A note about the shareware concept
  293.           ----------------------------------
  294.  
  295.           Just to make your conscience uneasy,  consider this.  In the past
  296.           I've written stuff on a write-it-when-I-need-it basis. Sometimes,
  297.           when a piece of software came in particularly handy, I decided to
  298.           distribute it. I granted permission to anyone to use the software
  299.           absolutely free, but I asked to  be  sent  a  netmail  message, a
  300.           postcard, or whatever, when someone decided to use my stuff.
  301.           Since then, I've seen my programs popping up in the most unlikely
  302.           places. So people actually use it,  which gives  me a  real kick.
  303.           But the  number of  reactions I  got was very disappointing. This
  304.           may be  due  to  the  fact  that  I  never  crippled distribution
  305.           versions. This sounds ridiculous, and, if true, it is.
  306.           So, when  people will use my software (in which, by the way, I've
  307.           invested a considerable amount of time), but consider it too much
  308.           trouble to  even drop me a netmail message, this may very well be
  309.           the last program from me. This time it's  really going  to depend
  310.           on user response. If I don't get any - again - then I won't spend
  311.           too much time at the keyboard next time. On the  other hand, any-
  312.            and I  mean *any*  - reaction  is an  impulse for me to continue
  313.  
  314.                                                 5
  315.  
  316.  
  317.  
  318.  
  319.           with projects like these. I'm sorry to put  it this  bluntly, but
  320.           that's the way it is. It's all in your hands now. 
  321.           If you  don't use the stuff, fine. But at least drop me a line to
  322.           let me know what you think  of it.  If you're  experimenting with
  323.           this,  the  odds  are  that  you  know  how  to send me a netmail
  324.           message. If not, ask the nearest SysOp, he'll be more  than happy
  325.           to instruct you.
  326.           If, on  the other  hand, you  decide to  use it, even better! But
  327.           register the stuff. It's  cheap,  and  it  will  keep  me  at the
  328.           keyboard to write something even better.
  329.  
  330.           OK -  some have hinted that I didn't get any reactions because my
  331.           documentation intro's tend to get long-winded... so let's  get on
  332.           with it!
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.                                                 6
  379.  
  380.  
  381.  
  382.  
  383.           ============================================================
  384.           2. TECHNICAL BACKGROUND INFORMATION
  385.           ============================================================
  386.  
  387.  
  388.           A BRIEF OVERVIEW OF THE HUDSON MESSAGE BASE
  389.           -------------------------------------------
  390.  
  391.           It is beyond the scope of this text to explain the Hudson message
  392.           base in detail. For those who want to know more, see the original
  393.           specifications, if you can find 'em.
  394.  
  395.           The  Hudson  message  base  consists  of  five  files.  Each file
  396.           consists of one or more records, the format of which you can find
  397.           in the MB_lib header file. A short description follows:
  398.  
  399.                MSGINFO.BBS    This file  is the only one with a fixed size.
  400.                               It contains  a single  record specifying info
  401.                               regarding the entire message base: the number
  402.                               of  messages  in  the  base,  the  lowest and
  403.                               highest number, and the amount of messages in
  404.                               each board.
  405.                MSGIDX.BBS     Index file. This file  contains a  record for
  406.                               each  message   in  the   base.  This  record
  407.                               specifies the message number and the board it
  408.                               can be  found in.  This file  can be used for
  409.                               searching for messages in a certain board.
  410.                MSGTOIDX.BBS   Index file. This file  contains a  record for
  411.                               each message in the base. The record contains
  412.                               the  who_to  field  from   the  corresponding
  413.                               message  header,  if  the message hasn't been
  414.                               received  by  the  user  yet.  (Mail  readers
  415.                               should overwrite  this record  when a message
  416.                               has been read.) This  file  can  be  used for
  417.                               searching  for  unread  messages to a certain
  418.                               user.
  419.                MSGHDR.BBS     Index file. This file  contains a  record for
  420.                               each message in the base. The records contain
  421.                               the header of the  corresponding message. Two
  422.                               fields in  this header  specify the number of
  423.                               the first text block of the  message, and the
  424.                               number of text blocks.
  425.                MSGTEXT.BBS    Ah,  this  is  the  one.  This  file contains
  426.                               blocks  of  text,  that  make  up  the actual
  427.                               message  text   body.  Start   en  length  of
  428.                               messages  are  specified  by  fields  in  the
  429.                               message header.
  430.  
  431.           The files  marked as  'Index file' have indeed an index function.
  432.           That means that record  n  in  one  index  file  corresponds with
  433.           record n  in another  index file. In other words, if a search for
  434.           unread mail  in MSGTOIDX.BBS  results in  a search  hit at record
  435.           100,  you  should  examine  record  100 in MSGIDX.BBS to find the
  436.           message number and board number, read record 100 in MSGHDR.BBS to
  437.           get  the  message  header,  and  examine this header to determine
  438.           which records to read from  MSGTEXT.BBS  to  dig  up  the message
  439.           text. But  you needn't worry about this - MB_lib will do that for
  440.           you.
  441.  
  442.                                                 7
  443.  
  444.  
  445.  
  446.  
  447.           Obviously, if one of  the index  files should  be corrupted, this
  448.           could mean loss of all messages in the base. Panic!
  449.           Well,  it's  not  as  bad  as  that.  If the files MSGHDR.BBS and
  450.           MSGTXT.BBS are  uncorrupted, the  other files  can be regenerated
  451.           from these by many message base maintenance utilities.
  452.  
  453.  
  454.           INTRODUCTION TO FILE LOCKING
  455.           ----------------------------
  456.  
  457.           In an  multi-tasking environment  where two or more processes are
  458.           sharing a single database or file, steps must be taken to prevent
  459.           file or database corruption when writing.
  460.           Picture this:  we read  a message  header, update  the reply link
  461.           pointers, and write it back. Nothing wrong so far. Now  try this:
  462.           we  read  a  file  header.  While  we're modifying the reply link
  463.           pointers, another  process  (like  another  instance  of  the BBS
  464.           program handling  another line)  also reads  the header. We write
  465.           our modified header back, after which the other  process does the
  466.           same, THEREBY  OVERWRITING THE MODIFICATIONS WE JUST MADE. Voila:
  467.           one corrupt message base.
  468.           To prevent all this, we use file locking. Before modifying one of
  469.           the files, we lock the message base. That is: we indicate then no
  470.           other process may write to the  files  at  this  moment.  Then we
  471.           read  and  modify  our  records,  write them back, and proceed to
  472.           unlock the message  base.  Other  operating  systems  than MS-DOS
  473.           (Unix for example) handle this for us, but if we're using MS-DOS,
  474.           we must do it ourselves. Thanks a bundle, MicroSoft.
  475.           MB_lib meets the official  Remote  Access  Locking Specification.
  476.           That means  that we  don't use  file locking in the normal sense,
  477.           relying on SHARE to provide the  services that  plain DOS doesn't
  478.           offer. Instead,  the files  are locked  outside their boundaries,
  479.           while RA checks for a lock just there. In the  meantime, a 0-byte
  480.           file  in  RA's  semaphore  file  directory  can indicate that the
  481.           message base must be unlocked NOW. So, as  I said,  it's not real
  482.           record  locking  in  the  normal  (OS)  sense. See the RA locking
  483.           specification for details.
  484.           Should you use file  locking when  writing a  program? YES!!! You
  485.           may not  be running  a multi-line  BBS, but somebody else may, so
  486.           that your program would corrupt the  message base  of that system
  487.           if you didn't use file locking.
  488.           MB_lib provides  two functions for easy locking and unlocking the
  489.           message base, so that you won't  have much  trouble handling this
  490.           properly.
  491.           Since  other  processes  can't  write while we've got the message
  492.           base locked,  we  should  unlock  it  regularly.  When performing
  493.           several write operations at a time, for example while changing an
  494.           entire message, you should use the following locking  / unlocking
  495.           sequences:
  496.           Changing a message header:
  497.                - Lock the message base
  498.                - Read the message header
  499.                - Modify it
  500.                - Write it back
  501.                - Unlock the message base
  502.           Writing new message text when the message header exists:
  503.                - Create message text
  504.                - Lock the message base
  505.  
  506.                                                 8
  507.  
  508.  
  509.  
  510.  
  511.                - Read the header
  512.                - Write message text
  513.                - Modify header
  514.                - Write back header
  515.                - Unlock message base
  516.           The same  goes for  *any* write  operation (create, modify, kill,
  517.           whatever) to  the message  base. Lock  the message  base, do your
  518.           modification,  unlock,  lock,  do  another  modification, unlock.
  519.           Always lock as short as possible. If you should need  to lock the
  520.           message base  for more  than 15  seconds at a time, you must take
  521.           some special precautions. See the document  RALCK003, enclosed in
  522.           this package, for details.
  523.  
  524.  
  525.           HOW TEXT IS STORED IN MEMORY
  526.           ----------------------------
  527.  
  528.           The size  of a  message text  body is unknown. The Hudson message
  529.           base allows - in theory - for  a  maximum  text  size  of  16 Mb,
  530.           though  many  BBS  and  mail processor packages can't handle more
  531.           than 8 or 16 kb. Therefore  it  is  wise  not  to  write messages
  532.           larger than 8 kb.
  533.           Anyway, we  can't allocate a fixed data space for a message text.
  534.           Therefore, text space is dynamically allocated.
  535.           Text  is  manipulated  with  a  so-called  text  handle.  For the
  536.           technically inclined:  this text  handle is actually a pointer to
  537.           the beginning of a linked list of records, consisting of pointers
  538.           to text blocks and pointers to the next record in the chain.
  539.           Text handles  are variables  of type  M_TEXT. You  declare a text
  540.           handle as follows:
  541.  
  542.           M_TEXT msgtxt;      /* Text handle to manipulate message text */
  543.  
  544.           That's all! Text  handles  are  returned  by  functions  like the
  545.           msg_read_text () and txt_new () functions. For example:
  546.  
  547.           msgtxt = msg_read_text (& header);  /* Read message text */
  548.  
  549.           To dump  this text  to, say,  the screen,  you use  the same text
  550.           handle:
  551.  
  552.           txt_dump (msgtxt, printline, margin, NOKLUDGES);
  553.  
  554.           It's a simple as that!
  555.  
  556.  
  557.           HOW MB_LIB HANDLES ERROR TRAPPING
  558.           ---------------------------------
  559.  
  560.           This may be news  to some  programmers... <grin>  but many things
  561.           can go  wrong while a program is running, and it is wise to check
  562.           for errors, so that when (not  if) an  error occurs,  the program
  563.           can gracefully  exit. Many  programs, especially those written in
  564.           Pascal for some reason, lack  airtight  error  trapping,  so that
  565.           they sometimes  exit with  the highly informative message RUNTIME
  566.           ERROR AT 1234:ABCD (or some other address). Anyway,  I've labored
  567.           to make error trapping in MB_lib as foolproof as possible.
  568.  
  569.  
  570.                                                 9
  571.  
  572.  
  573.  
  574.  
  575.           Since library  code never  should get  in the way of whatever the
  576.           application is  doing, error  trapping is  very flexible. Library
  577.           routines do  not exit to the OS. Library codes do not print error
  578.           messages. Nor  do  they  generate  beeps  or  anything  else. The
  579.           application programmer can do all this if desired.
  580.           Every  library  function  that  can  encounter an error returns a
  581.           completion code. This code usually is zero to indicate error-free
  582.           completion,  or  non-zero  if  an  error  was  encountered.  When
  583.           functions are supposed to return  a  number  (like  a  message or
  584.           record number),  the error completion code is -1, otherwise it is
  585.           an integer indication the nature of the error. For example:
  586.  
  587.           if (msg_open ("C:\\MSGBASE"))
  588.             error ();    /* Invoke programmer-supplied error handler */
  589.  
  590.           The programmer has two global variables  at his/her  disposal, to
  591.           determine the  nature of  the error.  When an error occurs, these
  592.           variables are automatically set to indicate what went  wrong, and
  593.           can be used in an error handler.
  594.           First,  there  is  the  int errortype variable. This variable can
  595.           have the following values:
  596.  
  597.           NOT_ERR (0x00)   /* No error                         */
  598.           MEM_ERR (0x01)   /* Memory error - out of memory     */
  599.           FRD_ERR (0x02)   /* File read error                  */
  600.           FWR_ERR (0x03)   /* File write error                 */
  601.           FCR_ERR (0x04)   /* File create error                */
  602.           MNO_ERR (0x05)   /* Message base not open error      */
  603.           IRN_ERR (0x06)   /* Invalid record no., out of bound */
  604.           MBC_ERR (0x07)   /* Msg base corrupt                 */
  605.  
  606.           THIS  VALUE  ALSO  APPLIES  TO  THE  FUNCTION  COMPLETION  CODES!
  607.           Examining either  the completion  code or  the errortype variable
  608.           can be used to trap errors.
  609.           Then there is the  char errorstring  [] variable.  This string is
  610.           filled  with  a  message  telling  the  user  what went wrong, in
  611.           readable text. 
  612.  
  613.           Using these two variables, an error handler could look like this:
  614.  
  615.           void error_exit (void) {
  616.             printf ("%cError %d accessing message base:\n%s\n",
  617.                      BELL, errortype, errorstring);
  618.             exit (1);
  619.           }
  620.  
  621.           Because MB_lib routines do not exit to the OS or  print anything,
  622.           you won't  get problems  when, for example, an error occurs while
  623.           in graphics mode. On the other  hand, if  you always  remember to
  624.           check completion  codes, you  will be  able to handle any kind of
  625.           error, critical or non-critical.
  626.  
  627.  
  628.           USE OF THE REGISTRATION KEY
  629.           ---------------------------
  630.  
  631.           Users who register their copy of MB_lib will  receive a registra-
  632.           tion key.  This key  is a  small file, that should be included in
  633.  
  634.                                                10
  635.  
  636.  
  637.  
  638.  
  639.           the program at the top of the source listing. Typically you would
  640.           add a     include "mb_lib.key"    statement to your program along
  641.           with the include statements for, say, the stdio.h file.
  642.           That  is  all!  The  registration  key  does  not  take  up extra
  643.           code/data space  in the  compiled executables. The only thing you
  644.           will notice is that the compiled  program no  longer displays the
  645.           'unregistered' message when running.
  646.           With the key, you can recompile your programs for distribution.
  647.  
  648.  
  649.           HOW MB_LIB IS DIVIDED INTO SEGMENTS
  650.           -----------------------------------
  651.  
  652.           Because the  whole library  is a large chunk of code, it would be
  653.           difficult to handle at  once. Therefore,  the library  is divided
  654.           into  segments.  This  provides  a  reasonable compromise between
  655.           efficiency and code size. If a  segment  isn't  used,  it  is not
  656.           linked to your executable.
  657.           The  functions  in  each  segment  are  discussed  in  a separate
  658.           chapter. The segments have the following functions:
  659.  
  660.           TEXT      Functions to handle text
  661.           ACCESS    Functions to access the message base
  662.           LOCK      Functions to  take  care  of  message  base  locking to
  663.                     enable  your  programs  to  run  in  a multi-tasking or
  664.                     multi-line BBS environment
  665.           MANIP     Message manipulation functions
  666.           READ      Functions to read records and messages
  667.           WRITE     Functions to write records and messages
  668.           SEARCH    Functions to search for messages
  669.           NETMAIL   This segment contains all functions to  handle messages
  670.                     in the  *.MSG format  (like netmail  messages with most
  671.                     mailers).
  672.  
  673.  
  674.  
  675.  
  676.  
  677.  
  678.  
  679.  
  680.  
  681.  
  682.  
  683.  
  684.  
  685.  
  686.  
  687.  
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.                                                11
  699.  
  700.  
  701.  
  702.  
  703.           ============================================================
  704.           3. TYPES, VARIABLES AND DEFINES
  705.           ============================================================
  706.  
  707.           =======================
  708.           M_TEXT
  709.           =======================
  710.  
  711.           Name           M_TEXT - text handle type
  712.  
  713.           Usage          M_TEXT <handlename>
  714.  
  715.           Description    As explained  above,  a  text  handle  is  used to
  716.                          manipulate message  text. A  variable of this type
  717.                          is returned by functions like txt_new ().
  718.  
  719.           See also       The background information  given  above,  and the
  720.                          reference  section  on  the txt_new () (and other)
  721.                          functions.
  722.  
  723.           Example        M_TEXT msgtext;   /* Text handle */
  724.  
  725.  
  726.           =======================
  727.           msginfo
  728.           =======================
  729.  
  730.           Name           msginfo - a global MSGINFO.BBS record  for various
  731.                          purposes
  732.  
  733.           Usage          MSGINFO_RECORD msginfo;
  734.  
  735.           Description    Since MSGINFO.BBS  contains only one record, which
  736.                          can have only one value, it makes sense  to define
  737.                          one  global  record  in which this information can
  738.                          be stored.  Instead of  reading the  file over and
  739.                          over  again  to  a  locally  defined  record, this
  740.                          variable provides one record which can be referred
  741.                          to  when   MSGINFO.BBS  data  is  needed  for  any
  742.                          purpose.
  743.  
  744.           See also       msg_read_info ();
  745.  
  746.  
  747.           ========================
  748.           errortype
  749.           ========================
  750.  
  751.           Name           errortype - indicate what went wrong
  752.  
  753.           Usage          int errortype;
  754.  
  755.           Description    The  errortype  variable   is   set   when  MB_lib
  756.                          encounters  an  error.  It  can have the following
  757.                          values:
  758.  
  759.                          NOT_ERR        No error
  760.                          MEM_ERR        Memory error (out of memory)
  761.  
  762.                                                12
  763.  
  764.  
  765.  
  766.  
  767.                          FRD_ERR        File read error
  768.                          FWR_ERR        File write error
  769.                          FCR_ERR        File creation error
  770.                          MNO_ERR        Message  base   not  opened  before
  771.                                         accessing it
  772.                          IRN_ERR        Invalid record number specified for
  773.                                         read or  write,  attempt  to access
  774.                                         files outside boundaries
  775.                          MBC_ERR        Message   base   corrupt  -  header
  776.                                         specifies non-existent records
  777.  
  778.           Remarks        These values also apply  to  the  completion codes
  779.                          returned by  the functions  which do  not return a
  780.                          record or message number.  It  is  set  when *any*
  781.                          function encounters an error. Checking it is up to
  782.                          you. However, errortype may  have  been  set  by a
  783.                          previous function after which you didn't check. In
  784.                          general, using completion codes to trap  errors is
  785.                          the most reliable way.
  786.  
  787.           See also       errorstring
  788.  
  789.           Example        See errorstring
  790.  
  791.  
  792.           ========================
  793.           errorstring
  794.           ========================
  795.  
  796.           Name           errorstring - tell the user what went wrong
  797.  
  798.           Usage          char errorstring []
  799.  
  800.           Description    The  errorstring  variable  is  set  whenever  the
  801.                          errortype variable is set.  It  contains  a string
  802.                          telling you  in readable text what went wrong. The
  803.                          string is not \n terminated.
  804.  
  805.           Remarks        See errortype
  806.  
  807.           See also       errortype
  808.  
  809.           Example        void errorexit (void) {    /* Exit with error */
  810.                            putchar (BELL);
  811.                            printf ("MB_lib error %d: %s\n", errortype,
  812.                            errorstring);
  813.                            exit (1);
  814.                          }
  815.  
  816.  
  817.           =======================
  818.           Various defines
  819.           =======================
  820.  
  821.           For your convenience, the following values  have been  defined in
  822.           MB_lib.h:
  823.  
  824.  
  825.  
  826.                                                13
  827.  
  828.  
  829.  
  830.  
  831.                     HCR       Hard carriage  return to  indicate the end of
  832.                               a paragraph in messages
  833.                     SCR       Soft carriage  return, may  be reformatted by
  834.                               message readers
  835.                     LF        Line feed
  836.                     KLUDGE    The  kludge  delimiter.  If this is the first
  837.                               character on a line, the rest of that line up
  838.                               to the first HCR will be used as a kludge.
  839.                     BELL      The bell character
  840.                     KLUDGES   Indicates  that   the  txt_dump  ()  function
  841.                               should dump kludges
  842.                     NOKLUDGES Indicates  that  the  txt_dump   ()  function
  843.                               should not  dump kludges. See txt_dump () for
  844.                               details.
  845.  
  846.  
  847.           =======================
  848.           Message attributes
  849.           =======================
  850.  
  851.  
  852.           #define MA_DELETED      0x01    /* Message attributes               */
  853.           #define MA_UNSENT       0X02
  854.           #define MA_NETMAIL      0X04
  855.           #define MA_PRIVATE      0X08
  856.           #define MA_RECEIVED     0X10
  857.           #define MA_UNMOVED      0X20
  858.           #define MA_LOCAL        0X40
  859.  
  860.           #define NA_KILL         0X01    /* Hudson netmail attributes        */
  861.           #define NA_SENT         0X02
  862.           #define NA_FILE         0X04
  863.           #define NA_CRASH        0X08
  864.           #define NA_RECEIPT      0X10
  865.           #define NA_AUDIT        0X20
  866.           #define NA_RETURN       0X40
  867.  
  868.           #define NM_PRIVATE      0X0001  /* Opus (*.MSG) Netmail attributes  */
  869.           #define NM_CRASH        0x0002
  870.           #define NM_RECEIVED     0x0004
  871.           #define NM_SENT         0x0008
  872.           #define NM_FILE         0x0010
  873.           #define NM_TRANSIT      0x0020
  874.           #define NM_ORPHAN       0x0040
  875.           #define NM_KILL         0x0080
  876.           #define NM_LOCAL        0x0100
  877.           #define NM_HOLD         0x0200
  878.           #define NM_UNUSED       0x4000
  879.           #define NM_REQUEST      0x0800
  880.           #define NM_RECEIPT      0x1000
  881.           #define NM_ISRECEIPT    0x2000
  882.           #define NM_AUDIT        0x4000
  883.           #define NM_UPDATEREQ    0x8000
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890.                                                14
  891.  
  892.  
  893.  
  894.  
  895.           =======================
  896.           Record structures
  897.           =======================
  898.  
  899.           The following structures make up the message base file records. BEWARE!
  900.           Since the strings in the Hudson message base are Pascal-format strings,
  901.           you should NEVER read  or  write  message  base  records  yourself, but
  902.           instead  use  the  functions  provided  in  MB_lib,  so that the proper
  903.           conversion can be performed.
  904.           These structures all use C-style  strings  -  you  needn't  worry about
  905.           formats here.  Just remember  to use  the MB_lib  functions for message
  906.           base I/O. That's what they're for, anyway, so why would you want  to do
  907.           otherwise?
  908.  
  909.           typedef struct {               /* MSGINFO.BBS structure definition */
  910.             unsigned int low_msg;        /* Lowest msg # in message base     */
  911.             unsigned int high_msg;       /* Highest msg # in message base    */
  912.             unsigned int total_msgs;     /* Total # of messages in base      */
  913.             unsigned int total_on_board [200];   /* Number of msgs / board   */
  914.           } MSGINFO_RECORD;
  915.  
  916.           typedef struct {               /* MSGIDX.BBS structure definition  */
  917.             int msg_num;                 /* Message #                        */
  918.             unsigned char board;         /* Board # where msg is stored      */
  919.           } MSGIDX_RECORD;
  920.  
  921.           typedef char MSGTOIDX_RECORD [36];  /* MSGTOIDX.BBS structure def. */
  922.  
  923.           typedef struct {               /* MSGHDR.BBS structure definition  */
  924.             int msgnum;                  /* Message number                   */
  925.             unsigned int prev_reply;     /* Msg # of previous reply, 0 if no */
  926.             unsigned int next_reply;     /* Msg # of next reply, 0 if none   */
  927.             unsigned int times_read;     /* # of times msg was read, UNUSED  */
  928.             unsigned int start_block;    /* Record # of msg in MSGTXT.BBS    */
  929.             unsigned int num_blocks;     /* # of records in MSGTXT.BBS       */
  930.             unsigned int dest_net;       /* Destination net                  */
  931.             unsigned int dest_node;      /* Destination node                 */
  932.             unsigned int orig_net;       /* Origin net                       */
  933.             unsigned int orig_node;      /* Origin node                      */
  934.             unsigned char dest_zone;     /* Destination zone                 */
  935.             unsigned char orig_zone;     /* Origin zone                      */
  936.             unsigned int cost;           /* Cost (Netmail)                   */
  937.             unsigned char msg_attr;      /* Msg attributes. Bits as follows: */
  938.                                          /* 0 : Deleted                      */
  939.                                          /* 1 : Unsent                       */
  940.                                          /* 2 : Netmail                      */
  941.                                          /* 3 : Private                      */
  942.                                          /* 4 : Received                     */
  943.                                          /* 5 : Unmoved outgoing echo        */
  944.                                          /* 6 : Local                        */
  945.                                          /* 7 : RESERVED                     */
  946.             unsigned char net_attr;      /* Netmail attributes. Bits follow: */
  947.                                          /* 0 : Kill/Sent                    */
  948.                                          /* 1 : Sent                         */
  949.                                          /* 2 : File attach                  */
  950.                                          /* 3 : Crash                        */
  951.                                          /* 4 : Receipt request              */
  952.                                          /* 5 : Audit request                */
  953.  
  954.                                                15
  955.  
  956.  
  957.  
  958.  
  959.                                          /* 6 : Is a return receipt          */
  960.                                          /* 7 : RESERVED                     */
  961.             unsigned char board;         /* Message board #                  */
  962.             char post_time [6];          /* Time message was posted          */
  963.             char post_date [9];          /* Date message was posted          */
  964.             char who_to [36];            /* Recipient to whom msg is sent    */
  965.             char who_from [36];          /* Sender who posted message        */
  966.             char subject [73];           /* Subject line of message          */
  967.           } MSGHDR_RECORD;
  968.  
  969.           typedef struct {               /* MSGTXT.BBS structure definition  */
  970.             unsigned char str_len;       /* This string is stored in memory  */
  971.             char str_txt [255];          /*  in Pascal format to reduce      */
  972.           } MSGTXT_RECORD;               /*  overhead, so take care!         */
  973.  
  974.  
  975.           /* The strings in the *.MSG file header (Opus style) aren't Pascal */
  976.           /* type strings but have the 'normal' ASCIIZ  format.              */
  977.  
  978.           typedef struct {               /* OPUS-style (*.MSG) msg format    */
  979.             char who_from [36];          /* Sender who posted message        */
  980.             char who_to [36];            /* Recipient  to whom msg is sent   */
  981.             char subject [72];           /* Subject line of message          */
  982.             char datetime [20];          /* Date/time msg was last edited    */
  983.             unsigned int times_read;     /* # of times message was read      */
  984.             unsigned int dest_node;      /* Destination node                 */
  985.             unsigned int orig_node;      /* Origin node                      */
  986.             unsigned int cost;           /* Cost to send netmail msg         */
  987.             unsigned int orig_net;       /* Origin net                       */
  988.             unsigned int dest_net;       /* Destination net                  */
  989.             unsigned int dest_zone;      /* Destination zone  (These fields) */
  990.             unsigned int orig_zone;      /* Origin zone       (were padded ) */
  991.             unsigned int dest_point;     /* Destination point (with 8 0's  ) */
  992.             unsigned int orig_point;     /* Origin point      (in FSC-0001 ) */
  993.             unsigned int reply_to;       /* Msg # to which this one replies  */
  994.             unsigned int attribute;      /* Msg attributes. Bits as follows: */
  995.                                          /* 0  : Private                     */
  996.                                          /* 1  : Crash                       */
  997.                                          /* 2  : Received                    */
  998.                                          /* 3  : Sent                        */
  999.                                          /* 4  : File attached               */
  1000.                                          /* 5  : In transit                  */
  1001.                                          /* 6  : Orphan                      */
  1002.                                          /* 7  : Kill when sent              */
  1003.                                          /* 8  : Local                       */
  1004.                                          /* 9  : Hold for pickup             */
  1005.                                          /* 10 : UNUSED                      */
  1006.                                          /* 11 : File request                */
  1007.                                          /* 12 : Return receipt request      */
  1008.                                          /* 13 : Is a return receipt         */
  1009.                                          /* 14 : Audit request               */
  1010.                                          /* 15 : File update request         */
  1011.             unsigned int next_reply;     /* Next msg in reply chain          */
  1012.           } NET_RECORD;
  1013.  
  1014.  
  1015.  
  1016.  
  1017.  
  1018.                                                16
  1019.  
  1020.  
  1021.  
  1022.  
  1023.           ============================================================
  1024.           4. TEXT SERVICES
  1025.           ============================================================
  1026.  
  1027.           =======================
  1028.           txt_new ()
  1029.           =======================
  1030.  
  1031.           Name           txt_new - create a new message text body
  1032.  
  1033.           Usage          M_TEXT txt_new (char * string);
  1034.  
  1035.           Description    The txt_new () function creates a new message text
  1036.                          body. This is typically the first function to call
  1037.                          when starting with a new message text. It requires
  1038.                          that you have defined  a  text  handle previously.
  1039.                          This  function  also  initializes the text handle.
  1040.                          The string argument may  either be  the first line
  1041.                          of the  new message text body, or may be a pointer
  1042.                          to a complete null-terminated block of text.
  1043.  
  1044.           Return value   Text handle, NULL if error. In case of  error, the
  1045.                          errortype  and  errorstring  variables  are set to
  1046.                          indicate the type of error.
  1047.  
  1048.           Remarks        The \n character is  not  translated  and  will be
  1049.                          placed  in  the  message  text body as a line feed
  1050.                          (LF).  It  will  be  ignored  by  message readers,
  1051.                          according  to  specifications  in FTS-0001. The \r
  1052.                          character generates a Hard Carriage Return (HCR).
  1053.  
  1054.           See also       txt_add (), txt_dispose ()
  1055.  
  1056.           Example        See txt_add ()
  1057.  
  1058.  
  1059.           =======================
  1060.           txt_add ()
  1061.           =======================
  1062.  
  1063.           Name           txt_add - add new text to an existing message text
  1064.                          body.
  1065.  
  1066.           Usage          int txt_add (M_TEXT texthandle, char * string);
  1067.  
  1068.           Description    The txt_add  () function  adds text to an existing
  1069.                          message text body.  When  starting  a  new message
  1070.                          text body, you MUST call txt_new () first in order
  1071.                          to initialize your text handle.
  1072.  
  1073.           Return value   Zero to indicate success, non-zero to  indicate an
  1074.                          error. See  the 'variables' section for completion
  1075.                          codes.
  1076.  
  1077.           Remarks        See txt_new ()
  1078.  
  1079.           See also       txt_new ()
  1080.  
  1081.  
  1082.                                                17
  1083.  
  1084.  
  1085.  
  1086.  
  1087.           Example        #include "mblib.h"
  1088.  
  1089.                          M_TEXT msgtext;
  1090.  
  1091.                          msgtext = txt_new ("This is line one. \n");
  1092.                          if (msgtext == NULL) {     /* ERROR! */
  1093.                            printf ("%s\n", errorstring);
  1094.                            exit (1);
  1095.                          }
  1096.                          if (txt_add (msgtext, "This is line two!\r"))
  1097.                            printf ("%s\n", errorstring);
  1098.  
  1099.  
  1100.           ========================
  1101.           txt_dispose
  1102.           ========================
  1103.  
  1104.           Name           txt_dispose - dispose of a message text body
  1105.  
  1106.           Usage          void txt_dispose (M_TEXT texthandle);
  1107.  
  1108.           Description    The txt_dispose () function is used  to dispose of
  1109.                          a block  of text. It releases the memory allocated
  1110.                          for the text body. Call this function after you've
  1111.                          finished with  a text  body (after processing it),
  1112.                          to free memory and the text handle for future use.
  1113.  
  1114.           Return value   None.
  1115.  
  1116.           See also       txt_new ()
  1117.  
  1118.  
  1119.           ========================
  1120.           txt_dump
  1121.           ========================
  1122.  
  1123.           Name           txt_dump - dump a message text to an output device
  1124.  
  1125.           Usage          int txt_dump (M_TEXT texthandle,
  1126.                          int (* output) (char *), unsigned char margin,
  1127.                          unsigned char kludges);
  1128.  
  1129.           Description    The txt_dump () function  is used  for all dumping
  1130.                          and printing  of message text. It is very flexible
  1131.                          and can be  used  to  print  message  text  to the
  1132.                          screen,  to  send  it  to  *any*  device, file, or
  1133.                          whatever, or to manipulate individual text lines.
  1134.                          It does so by  dividing text  into separate lines,
  1135.                          and  then  calling  a  programmer  supplied output
  1136.                          routine to process that  line. Because  you supply
  1137.                          the  output  routine  yourself,  you have complete
  1138.                          control over what happens to the text.
  1139.                          Text is wrapped to  a  specified  line  width (the
  1140.                          margin   parameter),   while  kludges  are  either
  1141.                          printed  or  not  printed,  as  specified  by  the
  1142.                          kludges parameter.
  1143.                          Because the  syntax is a bit complicated, here's a
  1144.                          list summarizing the accepted parameters:
  1145.  
  1146.                                                18
  1147.  
  1148.  
  1149.  
  1150.  
  1151.                            M_TEXT texthandle - this is the  text handle for
  1152.                          the text body you want to dump.
  1153.                            int (* output) (char *) - this looks complex but
  1154.                          it isn't. This parameter  is the  NAME (!)  of the
  1155.                          programmer  supplied  function  to  process a text
  1156.                          line. This function  should  accept  a  pointer to
  1157.                          char,  and  return  an  integer. This return value
  1158.                          should be zero to  indicate success  or nonzero to
  1159.                          indicate an error. See example below.
  1160.                            unsigned  char  margin  -  this is the number of
  1161.                          characters you want the text to be wrapped to
  1162.                            unsigned char kludges -  this  is  a  flag which
  1163.                          indicates whether  to print kludges or not. It can
  1164.                          have  the  value  KLUDGES  to  print  kludges,  or
  1165.                          NOKLUDGES to print no kludges.
  1166.  
  1167.           Return value   0 if success, -1 if the output routine encountered
  1168.                          an error (or at least returned a non-zero value).
  1169.  
  1170.           Remarks        WARNING: Because the actual output is  not handled
  1171.                          by  MB_lib,  an  error  encountered  by the output
  1172.                          routine will not set the errortype and errorstring
  1173.                          variables!   Error   handling  within  the  output
  1174.                          routine must be handled by the programmer.
  1175.                          The line passed to the output routine is not \n or
  1176.                          \r terminated.
  1177.  
  1178.           Example        #include "mblib.h"
  1179.                          #include <stdio.h>
  1180.  
  1181.                          int printline (char *);  /* Always prototype */
  1182.                          int saveline (char *);   /* these functions! */
  1183.  
  1184.                          M_TEXT msgtext;
  1185.                          FILE * savefile;
  1186.  
  1187.                          void main (void) {
  1188.                            msgtext = txt_new ("This is line one. \n");
  1189.                            if (msgtext == NULL) {     /* ERROR! */
  1190.                              printf ("%s\n", errorstring);
  1191.                              exit (1);
  1192.                            }
  1193.                            if (txt_add (msgtext, "This is line two!\r")) {
  1194.                              printf ("%s\n", errorstring);
  1195.                              exit (1);
  1196.                            }
  1197.                            txt_dump (msgtext, printline, 70, NOKLUDGES);
  1198.                              /* Print text to screen, margin 70 */
  1199.                            if ((savefile = fopen ("TEST", "w")) == NULL)
  1200.                              exit (1);
  1201.                            txt_dump (msgtext, saveline, 80, KLUDGES);
  1202.                              /* Save text to file, margin 80 + kludges */
  1203.                            txt_dispose (msgtext);
  1204.                            puts ("Done.");
  1205.                            fclose (savefile);
  1206.                          } /* main */
  1207.  
  1208.                          /* The following functions each output text */
  1209.  
  1210.                                                19
  1211.  
  1212.  
  1213.  
  1214.  
  1215.                          /* one line at a time                       */
  1216.  
  1217.                          int printline (char * line) {
  1218.                            puts (line);
  1219.                            return (0);    /* This always works */
  1220.                          } /* printline */
  1221.  
  1222.                          int saveline (char * line) {
  1223.                            if (!fprintf (savefile, "%s\n", line)) {
  1224.                              puts ("Error saving text!");
  1225.                              return (-1);    /* Error writing file */
  1226.                            }
  1227.                            else
  1228.                              return (0);
  1229.                          } /* saveline */
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.  
  1260.  
  1261.  
  1262.  
  1263.  
  1264.  
  1265.  
  1266.  
  1267.  
  1268.  
  1269.  
  1270.  
  1271.  
  1272.  
  1273.  
  1274.                                                20
  1275.  
  1276.  
  1277.  
  1278.  
  1279.           ============================================================
  1280.           5: MESSAGE BASE ACCESS SERVICES
  1281.           ============================================================
  1282.  
  1283.           ========================
  1284.           msg_open
  1285.           ========================
  1286.  
  1287.           Name           msg_open - open the message base
  1288.  
  1289.           Usage          int msg_open (char * msgbasepath);
  1290.  
  1291.           Description    Before you  can access  the message base, you MUST
  1292.                          call this  function to  open the  message base and
  1293.                          initialize the  message base I/O system. If you do
  1294.                          not, any attempts to access the  message base will
  1295.                          result in a MNO_ERR return value.
  1296.                          MB_lib tries  to locate  the message base files in
  1297.                          the path you supply.  If  the  files  don't exist,
  1298.                          msg_open () will create them.
  1299.  
  1300.           Return value   0 if  success, non-zero  if error. See the 'varia-
  1301.                          bles' section for completion codes.
  1302.  
  1303.           Remarks        Attempts to  open  the  message  base  when  it is
  1304.                          already open can't do any harm. MB_lib keeps track
  1305.                          of these things, just in case you do not. :-)
  1306.                          The message  base  path  may  be  terminated  by a
  1307.                          backslash, or not.
  1308.  
  1309.           See also       msg_close ()
  1310.  
  1311.           Example        if (msg_open ("C:\\MSGBASE"))
  1312.                            exit (1);   /* Error opening message base */
  1313.                          /* Your message handling goes here */
  1314.                          msg_close (); 
  1315.  
  1316.  
  1317.           ========================
  1318.           msg_close
  1319.           ========================
  1320.  
  1321.           Name           msg_close - close the message base
  1322.  
  1323.           Usage          void msg_close (void);
  1324.  
  1325.           Description    msg_close  closes  the  message  base  files after
  1326.                          you're done with them.  Closing  the  message base
  1327.                          when  it  isn't  open  can't  do any harm - MB_lib
  1328.                          checks first.
  1329.  
  1330.           Remarks        You don't rally need  to call  msg_close () before
  1331.                          exiting  your  program.  When  you have opened the
  1332.                          message  base,  MB_lib  checks  to  see  if you've
  1333.                          closed them again before exiting. So if you forget
  1334.                          to call  msg_close (),  there's no  harm done. But
  1335.                          from a  puristic point  of view, it's bad habit to
  1336.  
  1337.  
  1338.                                                21
  1339.  
  1340.  
  1341.  
  1342.  
  1343.                          rely on such mechanisms, it's neater  to close the
  1344.                          message base yourself.
  1345.  
  1346.           See also       msg_open ()
  1347.  
  1348.           Example        See msg_open ()
  1349.  
  1350.  
  1351.  
  1352.  
  1353.  
  1354.  
  1355.  
  1356.  
  1357.  
  1358.  
  1359.  
  1360.  
  1361.  
  1362.  
  1363.  
  1364.  
  1365.  
  1366.  
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401.  
  1402.                                                22
  1403.  
  1404.  
  1405.  
  1406.  
  1407.           ============================================================
  1408.           6: MESSAGE BASE LOCKING SERVICES
  1409.           ============================================================
  1410.  
  1411.           ========================
  1412.           msg_lock
  1413.           ========================
  1414.  
  1415.           Name           msg_lock - lock the message base to prevent writes
  1416.                          by other processes
  1417.  
  1418.           Usage          int msglock (char * semapath);
  1419.  
  1420.           Description    In a  multi-tasking  environment  (like multi-line
  1421.                          BBS'es) we  must take  precautions to prevent file
  1422.                          corruption.  The  details  on  this  are described
  1423.                          above (see Introduction to file locking).
  1424.                          The  semapath  string  must  specify the directory
  1425.                          that  is  used  by  Remote  Access  to  keep  it's
  1426.                          semaphore files in.
  1427.  
  1428.           Return value   -1 if  the there was a problem locking the message
  1429.                          base, otherwise 0.
  1430.  
  1431.           Remarks        If SHARE is not loaded before  locking the message
  1432.                          base, this  won't cause  an error.  I guess that's
  1433.                          the whole point for the rather exotic (and,  to my
  1434.                          taste, a little inelegant) RA locking method.
  1435.                          Since msg_lock  () allows for a 15 second timeout,
  1436.                          locking your message base could take this long.
  1437.  
  1438.           See also       msg_unlock ()
  1439.  
  1440.           Example        #include "mb_lib.h"
  1441.  
  1442.                          if (msg_lock == -1)
  1443.                            puts ("Error locking message base");
  1444.                          /* Or you could put a few retries here... */
  1445.                          else {
  1446.                            msg_write_new (& msgheader, msgtext);
  1447.                          /* msgheader and msgtext previously inited */
  1448.                          msg_unlock ();
  1449.  
  1450.  
  1451.           ========================
  1452.           msg_unlock
  1453.           ========================
  1454.  
  1455.           Name           msg_unlock  -   unlock  the   message  base  after
  1456.                          modifying it
  1457.  
  1458.           Usage          void msg_unlock (void);
  1459.  
  1460.           Description    Use  msg_unlock  ()  to  release file locks on the
  1461.                          message base, thereby enabling  other processes to
  1462.                          perform their write operations again.
  1463.  
  1464.           Remarks        See msg_lock ()
  1465.  
  1466.                                                23
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472.           See also       msg_lock ()
  1473.  
  1474.           Example        See msg_lock ()
  1475.  
  1476.  
  1477.  
  1478.  
  1479.  
  1480.  
  1481.  
  1482.  
  1483.  
  1484.  
  1485.  
  1486.  
  1487.  
  1488.  
  1489.  
  1490.  
  1491.  
  1492.  
  1493.  
  1494.  
  1495.  
  1496.  
  1497.  
  1498.  
  1499.  
  1500.  
  1501.  
  1502.  
  1503.  
  1504.  
  1505.  
  1506.  
  1507.  
  1508.  
  1509.  
  1510.  
  1511.  
  1512.  
  1513.  
  1514.  
  1515.  
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530.                                                24
  1531.  
  1532.  
  1533.  
  1534.  
  1535.           ============================================================
  1536.           7: MESSAGE MANIPULATION SERVICES
  1537.           ============================================================
  1538.  
  1539.           ========================
  1540.           msg_msgnr2recnr
  1541.           ========================
  1542.  
  1543.           Name           msg_msgnr2recnr - convert message number to record
  1544.                          number.
  1545.  
  1546.           Usage          long msg_msgnr2recnr (unsigned int msgnr);
  1547.  
  1548.           Description    Message numbers are not related to  record numbers
  1549.                          on  a  1:1  basis.  Since  messages  may have been
  1550.                          deleted from the message  base,  the  message base
  1551.                          records 0,  1, and  2 could,  for example, contain
  1552.                          the messages  100,  294  and  1583.  This function
  1553.                          converts  a  record  number  to  the corresponding
  1554.                          message number.
  1555.  
  1556.           Return value   The record number of  the message  we're searching
  1557.                          for, -1  if the  message was not found or an error
  1558.                          occurred. In the  latter  case  the  errortype and
  1559.                          errorstring variables are set.
  1560.  
  1561.           Remarks        If the message base contains message numbers which
  1562.                          have been set to  -1  (some  programs  do  this to
  1563.                          indicate   that   a   message  has  been  killed),
  1564.                          msg_msgnr2recnr () switches to  a different search
  1565.                          algorithm,  resulting  in  a    slight decrease in
  1566.                          performance.
  1567.  
  1568.           See also       msg_recnr2msgnr ();
  1569.  
  1570.           Example        #include "mb_lib.h"
  1571.  
  1572.                          long recnr;
  1573.                          int msgnr;
  1574.  
  1575.                          printf ("Enter message number: ");
  1576.                          scanf ("%d", & msgnr);
  1577.                          if ((recnr = msg_msgnr2recnr (msgnr)) == -1)
  1578.                            puts ("Message not found.");
  1579.                          else
  1580.                            printf ("Record nr. %l\n", recnr);
  1581.  
  1582.  
  1583.           ========================
  1584.           msg_recnr2msgnr
  1585.           ========================
  1586.  
  1587.           Name           msg_recnr2msgnr - convert record number to message
  1588.                          number.
  1589.  
  1590.           Usage          unsigned int msg_recnr2msgnr (long recnr);
  1591.  
  1592.  
  1593.  
  1594.                                                25
  1595.  
  1596.  
  1597.  
  1598.  
  1599.           Description    This  function  does  exactly  the opposite of the
  1600.                          msg_msgnr2recnr  ()  function:  it  retrieves  the
  1601.                          message  number  that  corresponds  with a certain
  1602.                          record number.
  1603.  
  1604.           Return value   The message number  of  the  message corresponding
  1605.                          with  the   specified  record,   -1  if  an  error
  1606.                          occurred. In this  case  the  errortype  an error-
  1607.                          string variables are set.
  1608.  
  1609.           See also       msg_msgnr2recnr ()
  1610.  
  1611.           Example        #include "mb_lib.h"
  1612.  
  1613.                          long recnr;
  1614.  
  1615.                          puts ("Message nr: 10");
  1616.                          if ((recnr = msg_recnr2msgnr (recnr)) == -1)
  1617.                            puts ("Error accessing message base");
  1618.                          else
  1619.                            printf ("Record nr: %l\n", recnr);
  1620.  
  1621.  
  1622.           ========================
  1623.           msg_hdr_clear
  1624.           ========================
  1625.  
  1626.           Name           msg_hdr_clear  -  clear  a  message header record,
  1627.                          e.g. set all fields in the header to zero.
  1628.  
  1629.           Usage          void msg_hdr_clear (MSGHDR_RECORD * hdr);
  1630.  
  1631.           Description    A message header record contains many fields, many
  1632.                          of which  should be  set to  0 when creating a new
  1633.                          message. Because the  fields  in  an uninitialized
  1634.                          header contain unknown values, we should initiali-
  1635.                          zed each field  before  using  this  header. Since
  1636.                          this  is  very  cumbersome, this function does the
  1637.                          job for you.
  1638.  
  1639.           Remarks        This  function   should  always   be  called  when
  1640.                          creating a new message header, otherwise unpredic-
  1641.                          table effects will occur.
  1642.  
  1643.           Example        #include "mb_lib.h"
  1644.  
  1645.                          MSGHDR_RECORD hdr;
  1646.  
  1647.                          msg_hdr_clear (& hdr);
  1648.                          strcpy (hdr.who_from, "Frank Van.wensveen");
  1649.                          strcpy (hdr.who_to, "All");
  1650.                          strcpy (hdr.subject, "Test");  /* That's all! */
  1651.  
  1652.           ========================
  1653.           msg_fixup4d
  1654.           ========================
  1655.  
  1656.  
  1657.  
  1658.                                                26
  1659.  
  1660.  
  1661.  
  1662.  
  1663.           Name           msg_fixup4d - convert the zone fields in a netmail
  1664.                          header to  an INTL kludge to overcome the FSC-0001
  1665.                          compliance problem.
  1666.  
  1667.           Usage          int msg_fixup4d (MSGHDR_RECORD * hdr, M_TEXT txt);
  1668.  
  1669.           Description    FSC-0001 describes the  format  of  a  basic *.MSG
  1670.                          netmail message  header. Since this document dates
  1671.                          from the time that  only 2D  addressing (net/node)
  1672.                          was used,  the definition had not defined any zone
  1673.                          and point address fields, but instead contains a 8
  1674.                          byte 'padding area'.
  1675.                          The header  used in this message base library is a
  1676.                          variant  that  is  widely  used  by  a  number  of
  1677.                          popular  software  packages,  but not supported by
  1678.                          all programs. This leads to problems. For example,
  1679.                          a  message  entered  in Remote Access addressed to
  1680.                          zone 3, will be  sent to  the zone  defined as the
  1681.                          mailers primary address instead.
  1682.                          To overcome  this incompatibility,  the INTL, FMPT
  1683.                          and TOPT kludges have been defined.  These kludges
  1684.                          are added  to the message text, usually at the top
  1685.                          of the message, although  at the  bottom they work
  1686.                          just as well. They have the following functions:
  1687.                               INTL 27:1331/703 2:285/504
  1688.                          indicates a message to 27:1331/703 from 2:285/504,
  1689.                               FMPT 2
  1690.                          indicates a message from point 2, and
  1691.                               TOPT 6
  1692.                          indicates a message to point 6.
  1693.                          So,   a   message   from,  say,  27:1331/703.5  to
  1694.                          2:285/504.2 will contain the following kludges:
  1695.                               INTL 2:285/504 27:1331/703
  1696.                               FMPT 5
  1697.                               TOPT 2
  1698.                          while the header has  to contain  only 1331/703 as
  1699.                          the origin address, and 285/504 as the destination
  1700.                          address. It  may contain  more, but  if the mailer
  1701.                          (or  any   other  software  used  to  process  the
  1702.                          message) doesn't support use of those  fields, the
  1703.                          extra header information is ignored. Software that
  1704.                          doesn't support these kludges simply ignores them,
  1705.                          as with all other kludges.
  1706.                          The  msg_fixup4d  function  allows  you  to easily
  1707.                          write messages  that  are  processed  correctly by
  1708.                          FSC-0001  compliant   software.  It  converts  the
  1709.                          undocumented zone  fields  in  the  Hudson netmail
  1710.                          header  into  a  INTL  kludge,  while  the related
  1711.                          net_fixup4d () function converts  the undocumented
  1712.                          zone  and  point  fields  in the *.MSG header into
  1713.                          INTL, FMPT and TOPT  kludges. If  these fields are
  1714.                          zero, however, the kludges are omitted.
  1715.  
  1716.           Return value   Zero on success, nonzero on error.
  1717.  
  1718.           Remarks        CAUTION:  The  fixup  functions  add  text  to the
  1719.                          specified  text  handle.  The  text  handle *MUST*
  1720.                          therefore be initialized, otherwise "unpredictable
  1721.  
  1722.                                                27
  1723.  
  1724.  
  1725.  
  1726.  
  1727.                          results"  (an  euphemism  for   a  total  screwup,
  1728.                          usually)  will   occur.  You  *must*  have  called
  1729.                          txt_new () previous to  calling msg_fixup4d  () or
  1730.                          net_fixup4d ().
  1731.  
  1732.           See also       net_fixup4d ()
  1733.  
  1734.           Example        #include "mb_lib.h"
  1735.  
  1736.                          MSGHDR_RECORD hdr;
  1737.                          M_TEXT msgtxt;
  1738.  
  1739.                          msg_hdr_clear (& hdr);
  1740.                          strcpy (hdr.who_from, "Frank Van.wensveen");
  1741.                          strcpy (hdr.who_to, "Sysop");
  1742.                          strcpy (hdr.subject, "Kludges");
  1743.                          hdr.dest_zone = 27;
  1744.                          hdr.orig_zone = 2;
  1745.                          hdr.dest_net = 1331;
  1746.                          hdr.orig_net = 285;
  1747.                          hdr.dest_node = 703;
  1748.                          hdr.orig_node = 504;
  1749.  
  1750.                          /* Now we have two possibilities. The first: */
  1751.                          msgtxt = txt_new ("");  /* THIS IS VITAL!! */
  1752.                          msg_fixup4d (& hdr, msgtxt);  /* Add kludges */
  1753.                          txt_add ("This message now contains kludges.\r");
  1754.  
  1755.                          /* The second: */
  1756.                          msgtxt = txt_new ("This message is kludgy!\r");
  1757.                          msg_fixup4d (& hdr, msgtxt); /* Add kludges */
  1758.                          /* Note the \r after the last message text! */
  1759.                          /* Without it, the kludge will be ignored!  */
  1760.  
  1761.                          msg_write_new (& hdr, msgtxt);   /* Save it */
  1762.  
  1763.  
  1764.  
  1765.  
  1766.  
  1767.  
  1768.  
  1769.  
  1770.  
  1771.  
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779.  
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785.  
  1786.                                                28
  1787.  
  1788.  
  1789.  
  1790.  
  1791.           ============================================================
  1792.           8: MESSAGE READING SERVICES
  1793.           ============================================================
  1794.  
  1795.           ========================
  1796.           msg_read_info
  1797.           ========================
  1798.  
  1799.           Name           msg_read_info -  read MSGINFO.BBS  into the global
  1800.                          msginfo record
  1801.  
  1802.           Usage          void msg_read_info (void);
  1803.  
  1804.           Description    MSGINFO.BBS does not contain multiple records, but
  1805.                          instead has  a fixed length, and contains only one
  1806.                          structure that can have only one value at  a time.
  1807.                          Therefore it  makes sense  not to read MSGINFO.BBS
  1808.                          over and over again to locally defined structures,
  1809.                          but  instead  use  a  global structure that can be
  1810.                          used  for  multiple  purposes.  This  structure is
  1811.                          msginfo. See the variables section for details.
  1812.  
  1813.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  1814.                          indicating  the  nature  of  the  error.  See  the
  1815.                          section on error handling for result codes.
  1816.  
  1817.           See also       msg_write_info ();
  1818.  
  1819.           Example        #include "mb_lib.h"
  1820.  
  1821.                          /* Message base is supposed to be open */
  1822.                          if (msg_read_info ())
  1823.                            exit (1);   /* Read error */
  1824.                          printf ("Number of messages in base: ");
  1825.                          printf ("%u\n", msginfo.total_msgs);
  1826.  
  1827.  
  1828.           ========================
  1829.           msg_read_hdr
  1830.           ========================
  1831.  
  1832.           Name           msg_read_hdr  -  read  a  message  header  from  a
  1833.                          specified record in MSGHDR.BBS.
  1834.  
  1835.           Usage          int msg_read_hdr (long recnr, 
  1836.                                            MSGHDR_RECORD * hdr);
  1837.  
  1838.           Description    This function  is used  to read  a message header.
  1839.                          Prior to  reading the header, the record number of
  1840.                          the message must  be  known.  This  number  can be
  1841.                          obtained from one of the search functions.
  1842.  
  1843.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  1844.                          indicating  the  nature  of  the  error.  See  the
  1845.                          section on error handling for result codes.
  1846.  
  1847.           See also       msg_write_hdr ()
  1848.  
  1849.  
  1850.                                                29
  1851.  
  1852.  
  1853.  
  1854.  
  1855.           Example        #include "mblib.h"
  1856.                          MSGHDR_RECORD myheader;
  1857.  
  1858.                          /* Reading the header in record 100: */
  1859.                          if (msg_read_hdr (100, & myheader))
  1860.                            exit (1);    /* Read error */
  1861.                          printf ("Subject: %s\n", myhdr.subject);
  1862.  
  1863.  
  1864.           ========================
  1865.           msg_read_idx
  1866.           ========================
  1867.  
  1868.           Name           msg_read_idx  -  read  a  message  header  from  a
  1869.                          specified record in MSGIDX.BBS.
  1870.  
  1871.           Usage          int msg_read_idx (long recnr, 
  1872.                                            MSGIDX_RECORD * idx);
  1873.  
  1874.           Description    This function is  used  to  read  a  message index
  1875.                          record. This  record specifies  the message number
  1876.                          and the board number of  a  message  in  a certain
  1877.                          record.  Prior  to  reading the record, the record
  1878.                          number of the message  must be  known. This number
  1879.                          can be obtained from one of the search functions.
  1880.  
  1881.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  1882.                          indicating  the  nature  of  the  error.  See  the
  1883.                          section on error handling for result codes.
  1884.  
  1885.  
  1886.           See also       msg_write_idx ()
  1887.  
  1888.           Example        #include "mblib.h"
  1889.                          MSGIDX_RECORD myidx;
  1890.  
  1891.                          /* Reading the index in record 100: */
  1892.                          if (msg_read_idx (100, & myidx))
  1893.                            exit (1);    /* Read error */
  1894.                          printf ("Msg nr: %d, board nr: %d",
  1895.                                  myidx.msg_num, myidx.board);
  1896.  
  1897.  
  1898.           ========================
  1899.           msg_read_toidx
  1900.           ========================
  1901.  
  1902.           Name           msg_read_toidx  -  read  a record from a specified
  1903.                          record in MSGTOIDX.BBS. 
  1904.  
  1905.           Usage          int msg_read_toidx (long recnr, 
  1906.                                              MSGTOIDX_RECORD * idx);
  1907.  
  1908.           Description    This  function  is  used  to  read  a MSGTOIDX.BBS
  1909.                          record.  Prior  to  reading the header, the record
  1910.                          number of the message  must be  known. This number
  1911.                          can be obtained from one of the search functions.
  1912.  
  1913.  
  1914.                                                30
  1915.  
  1916.  
  1917.  
  1918.  
  1919.                          The  obtained  record  specifies the user name the
  1920.                          message is sent to.  After  the  message  has been
  1921.                          received, this record should be overwritten by the
  1922.                          message reader. As a result, the MSGTOIDX file can
  1923.                          be searched for unreceived mail to a certain user.
  1924.  
  1925.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  1926.                          indicating  the  nature  of  the  error.  See  the
  1927.                          section on error handling for result codes.
  1928.  
  1929.           See also       msg_write_toidx ()
  1930.  
  1931.           Example        #include "mblib.h"
  1932.                          MSGTOIDX_RECORD addressee;
  1933.  
  1934.                          /* Reading addressee from record 100: */
  1935.                          if (msg_read_toidx (100, & addressee))
  1936.                            exit (1);    /* Read error */
  1937.                          printf ("To: %s\n", addressee);
  1938.  
  1939.  
  1940.           ========================
  1941.           msg_read_text
  1942.           ========================
  1943.  
  1944.           Name           msg_read_text -  read the  text of  a message, the
  1945.                          header of which is known.
  1946.  
  1947.           Usage          M_TEXT msg_read_text (MSGHDR_RECORD * hdr);
  1948.  
  1949.           Description    This function  is  used  to  read  the  text  of a
  1950.                          certain message. Because text is not just a single
  1951.                          record, more information than just a record number
  1952.                          is needed.  Therefore, the  message header must be
  1953.                          read prior to calling this function, and a pointer
  1954.                          to the  corresponding message  header is passed to
  1955.                          this read function.
  1956.  
  1957.           Return value   The text handle to be used  for the  text, NULL if
  1958.                          an error  occurred. In this case the errortype and
  1959.                          errorstring variables are set.
  1960.  
  1961.           See also       msg_write_text (), txt_dump ()
  1962.  
  1963.           Example        #include "mb_lib.h"
  1964.                          MSGHDR_RECORD msghdr;    /* Header      */
  1965.                          M_TEXT msgtxt;           /* Text handle */
  1966.  
  1967.                          /* Reading message in record 100 */
  1968.                          if (msg_read_hdr (100, & msghdr))
  1969.                            exit (1);    /* Read error */
  1970.                          msgtxt = msg_read_text (& msghdr);
  1971.                          if (msgtxt == NULL)
  1972.                            exit (1);    /* Read error */
  1973.                          printf ("Message %d:\n", msghdr.msgnum);
  1974.                          printf ("By: %s\nTo:%s\nRe:%s\n\n",
  1975.                                   msghdr.who_from, msghdr.who_to,
  1976.                                   msghdr.subject);
  1977.  
  1978.                                                31
  1979.  
  1980.  
  1981.  
  1982.  
  1983.                          txt_dump (msgtxt, printline, 70, NOKLUDGES);
  1984.                          /* Printline function defined elsewhere */
  1985.  
  1986.  
  1987.  
  1988.  
  1989.  
  1990.  
  1991.  
  1992.  
  1993.  
  1994.  
  1995.  
  1996.  
  1997.  
  1998.  
  1999.  
  2000.  
  2001.  
  2002.  
  2003.  
  2004.  
  2005.  
  2006.  
  2007.  
  2008.  
  2009.  
  2010.  
  2011.  
  2012.  
  2013.  
  2014.  
  2015.  
  2016.  
  2017.  
  2018.  
  2019.  
  2020.  
  2021.  
  2022.  
  2023.  
  2024.  
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.                                                32
  2043.  
  2044.  
  2045.  
  2046.  
  2047.           ============================================================
  2048.           9: MESSAGE WRITING SERVICES
  2049.           ============================================================
  2050.  
  2051.           ========================
  2052.           msg_write_info
  2053.           ========================
  2054.  
  2055.           Name           msg_write_info -  write the  global msginfo record
  2056.                          to MSGINFO.BBS
  2057.  
  2058.           Usage          void msg_write_info (void);
  2059.  
  2060.           Description    This function  is much  like msg_read_info, except
  2061.                          that it writes the global MSGINFO.BBS record back,
  2062.                          for example after it has been modified.
  2063.  
  2064.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  2065.                          indicating  the  nature  of  the  error.  See  the
  2066.                          section on error handling for result codes.
  2067.  
  2068.           See also       msg_read_info ();
  2069.  
  2070.           Example        #include "mb_lib.h"
  2071.  
  2072.                          /* Message base is supposed to be open */
  2073.                          if (msg_read_info ())
  2074.                            exit (1);   /* Read error */
  2075.                          /* The msginfo record is modified here */
  2076.                          if (msg_write_info ())
  2077.                            exit (1);   /* Write error */
  2078.  
  2079.  
  2080.           ========================
  2081.           msg_write_hdr
  2082.           ========================
  2083.  
  2084.           Name           msg_read_hdr  -   write  a  message  header  to  a
  2085.                          specified record in MSGHDR.BBS.
  2086.  
  2087.           Usage          int msg_write_hdr (long recnr, 
  2088.                                            MSGHDR_RECORD * hdr);
  2089.  
  2090.           Description    This function is used  to write  a message header.
  2091.                          Prior to  writing the header, the record number of
  2092.                          the message must  be  known.  This  number  can be
  2093.                          obtained  from  one  of  the search functions, or,
  2094.                          when  modifying  a  header,  it  is  usually known
  2095.                          before you need this function.
  2096.  
  2097.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  2098.                          indicating  the  nature  of  the  error.  See  the
  2099.                          section on error handling for result codes.
  2100.  
  2101.           See also       msg_read_hdr ()
  2102.  
  2103.           Example        #include "mblib.h"
  2104.                          MSGHDR_RECORD myheader;
  2105.  
  2106.                                                33
  2107.  
  2108.  
  2109.  
  2110.  
  2111.  
  2112.                          /* Modify the header in record 100: */
  2113.                          if (msg_read_hdr (100, & myheader))
  2114.                            exit (1);    /* Read error */
  2115.                          myheader.times_read ++;  /* Read once more */
  2116.                          if (msg_write_hdr (100, & myheader))
  2117.                            exit (1);    /* Write error */
  2118.  
  2119.  
  2120.           ========================
  2121.           msg_write_idx
  2122.           ========================
  2123.  
  2124.           Name           msg_write_idx  -  write  a  message  header  to  a
  2125.                          specified record in MSGIDX.BBS.
  2126.  
  2127.           Usage          int msg_write_idx (long recnr, 
  2128.                                            MSGIDX_RECORD * idx);
  2129.  
  2130.           Description    This function is much like msg_read_idx (), except
  2131.                          that it writes a record to MSGIDX.BBS.
  2132.  
  2133.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  2134.                          indicating  the  nature  of  the  error.  See  the
  2135.                          section on error handling for result codes.
  2136.  
  2137.           See also       msg_read_idx ()
  2138.  
  2139.           Example        #include "mblib.h"
  2140.                          MSGIDX_RECORD myidx;  /* Supposed to be inited */
  2141.  
  2142.                          /* Writing the index to record 100: */
  2143.                          if (msg_to_idx (100, & myidx))
  2144.                            exit (1);    /* Read error */
  2145.  
  2146.  
  2147.           ========================
  2148.           msg_write_toidx
  2149.           ========================
  2150.  
  2151.           Name           msg_write_toidx  -  write  a record to a specified
  2152.                          record in MSGTOIDX.BBS. 
  2153.  
  2154.           Usage          int msg_write_toidx (long recnr, 
  2155.                                              MSGTOIDX_RECORD * idx);
  2156.  
  2157.           Description    This  function  is  much  like  msg_read_toidx (),
  2158.                          except that  it writes a record to MSGIDX.BBS, for
  2159.                          example after modifying it.
  2160.  
  2161.           Return value   Zero  on  success,  a  nonzero  value   on  error,
  2162.                          indicating  the  nature  of  the  error.  See  the
  2163.                          section on error handling for result codes.
  2164.  
  2165.           See also       msg_read_toidx ()
  2166.  
  2167.           Example        #include "mblib.h"
  2168.                          MSGTOIDX_RECORD addressee;
  2169.  
  2170.                                                34
  2171.  
  2172.  
  2173.  
  2174.  
  2175.  
  2176.                          /* Reading addressee from record 100: */
  2177.                          if (msg_read_toidx (100, & addressee))
  2178.                            exit (1);    /* Read error */
  2179.                          printf ("To: %s\n", addressee);
  2180.                          strcpy (addressee, "* Received *");
  2181.                          /* Since the msg is no longer unreceived, */
  2182.                          /* mark it as such                        */
  2183.                          if (msg_write_toidx (100, & addressee)
  2184.                            exit (1);    /* Write error */
  2185.  
  2186.  
  2187.           ========================
  2188.           msg_write_text
  2189.           ========================
  2190.  
  2191.           Name           msg_write_text - write text  to a  message, either
  2192.                          modifying old text or creating new text.
  2193.  
  2194.           Usage          int msg_write_text (MSGHDR_RECORD * hdr,
  2195.                                              M_TEXT txt);
  2196.  
  2197.           Description    This function is typically used to modify existing
  2198.                          message text, or to add new  text to  a previously
  2199.                          written new  message header.  To create entire new
  2200.                          messages  from  scratch,  you'd   better  use  the
  2201.                          msg_write_new () function.
  2202.                          Whether the  text is  used as  a replacement or as
  2203.                          new  text  is  determined  by  the  message header
  2204.                          passed  to  the  function.  If the start_block and
  2205.                          num_blocks field in the  message header  are zero,
  2206.                          the  text  is  treated  as  new  text (since there
  2207.                          obviously isn't  any  old  text  with  these field
  2208.                          containing  zero).  Otherwise,  previous  text  is
  2209.                          replaced.
  2210.  
  2211.           Return value   Zero  on  success,  a  nonzero  value   on  error,
  2212.                          indicating  the  nature  of  the  error.  See  the
  2213.                          section on error handling for result codes.
  2214.  
  2215.           Remarks        Replaced  message  text  blocks  are  not actually
  2216.                          removed from  the message  base. You  need to pack
  2217.                          the message base  with  an  external  message base
  2218.                          maintenance utility to do this.
  2219.  
  2220.           See also       msg_read_text (), msg_write_new ()
  2221.  
  2222.           Example        #include "mb_lib.h"
  2223.                          MSGHDR_RECORD msghdr;    /* Header      */
  2224.                          M_TEXT msgtxt;           /* Text handle */
  2225.  
  2226.                          /* Reading message in record 100 */
  2227.                          if (msg_read_hdr (100, & msghdr))
  2228.                            exit (1);    /* Read error */
  2229.                          /* Now read text, add line, write it back */
  2230.                          msgtxt = msg_read_text (& msghdr);
  2231.                          if (msgtxt == NULL)
  2232.                            exit (1);    /* Read error */
  2233.  
  2234.                                                35
  2235.  
  2236.  
  2237.  
  2238.  
  2239.                          if (txt_add (msgtxt, "One more line..."))
  2240.                            exit (1);    /* Memory error */
  2241.                          if (msg_write_txt (& msghdr, msgtxt))
  2242.                            exit (1);    /* Error writing new text */
  2243.  
  2244.  
  2245.           ========================
  2246.           msg_write_new
  2247.           ========================
  2248.  
  2249.           Name           msg_write_new - write a new message to the message
  2250.                          base
  2251.  
  2252.           Usage          int msg_write_new (MSGHDR_RECORD * hdr,
  2253.                                             M_TEXT txt);
  2254.  
  2255.           Description    Ah - this is the one!  This function  is typically
  2256.                          used to  write a  new message to the message base.
  2257.                          Before calling this function you need to construct
  2258.                          a message  header and fill in the source, destina-
  2259.                          tion and subject fields (in case  of netmail, node
  2260.                          numbers  as  well),  fill  in the board number and
  2261.                          set the desired message attributes. You  also need
  2262.                          to create  a message  text. When you've got header
  2263.                          and text handy, all you need is call this function
  2264.                          (which will  set the other header fields for you).
  2265.  
  2266.           Return value   Zero  on  success,  a  nonzero  value   on  error,
  2267.                          indicating  the  nature  of  the  error.  See  the
  2268.                          section on error handling for result codes.
  2269.  
  2270.           Remarks        You must set unused  header fields  to zero  - the
  2271.                          msg_hdr_clear () function can be used for this. If
  2272.                          you  don't,  unpredicted  results  (this  being an
  2273.                          euphemism for a complete screwup) could occur.
  2274.  
  2275.           See also       msg_write_text (), msg_kill ()
  2276.  
  2277.           Example        #include "mb_lib.h"
  2278.                          MSGHDR_RECORD msghdr;
  2279.                          M_TEXT msgtxt;
  2280.  
  2281.                          /* Error checking left out to keep it short! */
  2282.                          /* In other words, this is quick and dirty.  */
  2283.                          main () {
  2284.                            msg_open ("C:\\MSGBASE");
  2285.                            msg_hdr_clear (& msghdr);
  2286.                            strcpy (msghdr.who_from, "Frank Van.wensveen");
  2287.                            strcpy (msghdr.who_to, "All");
  2288.                            strcpy (msghdr.subject, "See how easy it is?");
  2289.                            msghdr.board = 6; /* My local echomail board */
  2290.                            msghdr.msg_attr = MA_LOCAL;
  2291.                            msgtxt = txt_new ("See? Writing a message is ");
  2292.                            txt_add (msgtxt, "easy! Even I could do it!\r");
  2293.                            msg_lock ("C:\\SEMAFORE");
  2294.                            msg_write_new (& msghdr, msgtxt);
  2295.                            msg_unlock ();
  2296.                            msg_close ();
  2297.  
  2298.                                                36
  2299.  
  2300.  
  2301.  
  2302.  
  2303.                          }
  2304.  
  2305.  
  2306.           ========================
  2307.           msg_kill
  2308.           ========================
  2309.  
  2310.           Name           msg_kill - kill a message
  2311.  
  2312.           Usage          int msg_kill (long recnr);
  2313.  
  2314.           Description    The  msg_kill  ()  function  is  used  to  kill  a
  2315.                          message, the record number of which is specified.
  2316.  
  2317.           Return value   Zero  on  success,  a  nonzero  value   on  error,
  2318.                          indicating  the  nature  of  the  error.  See  the
  2319.                          section on error handling for result codes.
  2320.  
  2321.           Remarks        A killed message is not actually  removed from the
  2322.                          message  base.  To  do  this, you need to pack the
  2323.                          message  base   with  an   external  message  base
  2324.                          maintenance utility.
  2325.  
  2326.           Example        #include "mb_lib.h"
  2327.                          long recnr;
  2328.  
  2329.                          /* Killing message nr. 100 */
  2330.                          recnr = msg_msgnr2recnr (100);
  2331.                          if (recnr != -1)
  2332.                            msg_kill (recnr);
  2333.                          /* Error checking left out */
  2334.  
  2335.  
  2336.  
  2337.  
  2338.  
  2339.  
  2340.  
  2341.  
  2342.  
  2343.  
  2344.  
  2345.  
  2346.  
  2347.  
  2348.  
  2349.  
  2350.  
  2351.  
  2352.  
  2353.  
  2354.  
  2355.  
  2356.  
  2357.  
  2358.  
  2359.  
  2360.  
  2361.  
  2362.                                                37
  2363.  
  2364.  
  2365.  
  2366.  
  2367.           ============================================================
  2368.           10: MESSAGE SEARCH SERVICES
  2369.           ============================================================
  2370.  
  2371.           ========================
  2372.           msg_firstinboard
  2373.           ========================
  2374.  
  2375.           Name           msg_firstinboard -  find the  first message in the
  2376.                          specified board
  2377.  
  2378.           Usage          long msg_firstinboard (unsigned char board);
  2379.  
  2380.           Description    This message is used to find the RECORD  NUMBER of
  2381.                          the first  message in a certain board. You'll need
  2382.                          things like  this when  reading all  messages in a
  2383.                          certain  board  from  first  to  last or something
  2384.                          like that.
  2385.  
  2386.           Return value   The RECORD number  of  the  first  message  in the
  2387.                          specified board,  -1 if not found or error. In the
  2388.                          latter   case   the   errortype   and  errorstring
  2389.                          variables are set.
  2390.  
  2391.           See also       msg_lastinboard (), msg_nextinboard (),
  2392.                          msg_previnboard ()
  2393.  
  2394.           Example        See msg_nextinboard ();
  2395.  
  2396.  
  2397.           ========================
  2398.           msg_nextinboard
  2399.           ========================
  2400.  
  2401.           Name           msg_nextinboard  -  find  the  next message in the
  2402.                          same board as the message we've just read is in.
  2403.  
  2404.           Usage          long msg_nextinboard (long recnr);
  2405.  
  2406.           Description    After  calling  msg_firstinboard,  we've  got  the
  2407.                          record number  of the first message in that board.
  2408.                          This  function  finds  the  next  message  in that
  2409.                          board, using  the record  number of the previously
  2410.                          processed message as a starting point.
  2411.  
  2412.           Return value   The RECORD  number  of  the  next  message  in the
  2413.                          specified board,  -1 if not found or error. In the
  2414.                          latter   case   the   errortype   and  errorstring
  2415.                          variables are set.
  2416.  
  2417.           See also       msg_firstinboard (), msg_lastinboard (),
  2418.                          msg_previnboard ();
  2419.  
  2420.           Example        #include "mb_lib.h"
  2421.                          long recnr;
  2422.  
  2423.                          /* Listing messages in board 1 */
  2424.                          recnr = msg_firstinboard (1);
  2425.  
  2426.                                                38
  2427.  
  2428.  
  2429.  
  2430.  
  2431.                          while (recnr != -1) {
  2432.                            printf ("Message number:%d\n",
  2433.                                     msg_recnr2msgnr (recnr);
  2434.                            recnr = msg_nextinboard (recnr);
  2435.                          }
  2436.  
  2437.  
  2438.           ========================
  2439.           msg_lastinboard
  2440.           ========================
  2441.  
  2442.           Name           msg_lastinboard  -  find  the  last message in the
  2443.                          specified board.
  2444.  
  2445.           Usage          long msg_lastinboard (unsigned char board);
  2446.  
  2447.           Description    This message is identical to msg_firstinboard, but
  2448.                          returns the  number of the last message instead of
  2449.                          the first.
  2450.  
  2451.           Return value   The RECORD  number  of  the  last  message  in the
  2452.                          specified board,  -1 if not found or error. In the
  2453.                          latter   case   the   errortype   and  errorstring
  2454.                          variables are set.
  2455.  
  2456.           See also       msg_firstinboard (), msg_nextinboard (),
  2457.                          msg_previnboard ();
  2458.  
  2459.           Example        See msg_previnboard ();
  2460.  
  2461.  
  2462.           ========================
  2463.           msg_previnboard
  2464.           ========================
  2465.  
  2466.           Name           msg_previnboard - find the previous message in the
  2467.                          same board as the message we've just read is in.
  2468.  
  2469.           Usage          long msg_previnboard (long recnr);
  2470.  
  2471.           Description    This function is identical  to msg_nextinboard (),
  2472.                          except that it searches backwards.
  2473.  
  2474.           Return value   The RECORD  number of  the previous message in the
  2475.                          specified board, -1 if not found or error.  In the
  2476.                          latter   case   the   errortype   and  errorstring
  2477.                          variables are set.
  2478.  
  2479.           See also       msg_next_inboard, msg_lastinboard (),
  2480.                          msg_previnboard ();
  2481.  
  2482.           Example        #include "mb_lib.h"
  2483.                          long recnr;
  2484.  
  2485.                          /* Backward listing messages in board 1 */
  2486.                          recnr = msg_lastinboard (1);
  2487.                          while (recnr != -1) {
  2488.                            printf ("Message number:%d\n",
  2489.  
  2490.                                                39
  2491.  
  2492.  
  2493.  
  2494.  
  2495.                                     msg_recnr2msgnr (recnr);
  2496.                            recnr = msg_previnboard (recnr);
  2497.                          }
  2498.  
  2499.  
  2500.           ========================
  2501.           msg_firstto
  2502.           ========================
  2503.  
  2504.           Name           msg_firstto - find the first unreceived message to
  2505.                          a certain user
  2506.  
  2507.           Usage          long msg_firstto (MSGTOIDX_RECORD * idx);
  2508.  
  2509.           Description    This message  can be used to scan the message base
  2510.                          for unreceived  mail to  a certain  user. It scans
  2511.                          MSGTOIDX.BBS for  the user's  name and returns the
  2512.                          record number associated with  a  search  hit. You
  2513.                          can  then  proceed  to  read  the  message in this
  2514.                          record.
  2515.                          Software used for reading  the unreceived messages
  2516.                          should  overwrite   the  corresponding  record  in
  2517.                          MSGTOIDX.BBS to prevent the message from remaining
  2518.                          marked  as  unreceived.  Functions in MB_lib don't
  2519.                          take care of this, the programmer must do it.
  2520.  
  2521.           Return value   The RECORD number  of  the  first  message  to the
  2522.                          specified user,  -1 if  not found or error. In the
  2523.                          latter   case   the   errortype   and  errorstring
  2524.                          variables are set.
  2525.  
  2526.           See also       msg_nextto (), msg_lastto (), msg_prevto ()
  2527.  
  2528.           Example        See msg_nextto ()
  2529.  
  2530.  
  2531.           ========================
  2532.           msg_nextto
  2533.           ========================
  2534.  
  2535.           Name           msg_nextto  -  find  the  next message to the same
  2536.                          user as the one we just read was addressed to
  2537.  
  2538.           Usage          long msg_nextto (long recnr);
  2539.  
  2540.           Description    After calling msg_firstto,  we've  got  the record
  2541.                          number  of  the  first  message to a certain user.
  2542.                          This  function  finds  the  next  message  to that
  2543.                          user,  using  the  record number of the previously
  2544.                          processed message as a starting point.
  2545.  
  2546.           Return value   The RECORD  number  of  the  next  message  to the
  2547.                          specified user,  -1 if  not found or error. In the
  2548.                          latter   case   the   errortype   and  errorstring
  2549.                          variables are set.
  2550.  
  2551.           See also       msg_firstto (), msg_lastto (), msg_prevto ()
  2552.  
  2553.  
  2554.                                                40
  2555.  
  2556.  
  2557.  
  2558.  
  2559.           Example        #include "mb_lib.h"
  2560.                          long recnr;
  2561.                          MSGTOIDX_RECORD toidx;
  2562.  
  2563.                          strcpy (toidx, "Frank Van.wensveen");
  2564.                          recnr = msg_firstto (toidx);
  2565.                          puts ("Mail waiting for you:");
  2566.                          while (recnr != -1) {
  2567.                            printf ("Message number: %d\n",
  2568.                                     msg_recnr2msgnr (recnr);
  2569.                            recnr = msg_nextto (recnr);
  2570.                          }
  2571.  
  2572.  
  2573.           ========================
  2574.           msg_lastto
  2575.           ========================
  2576.  
  2577.           Name           msg_lastto - find the last unreceived message to a
  2578.                          certain user.
  2579.  
  2580.           Usage          long msg_lastto (MSGTOIDX_RECORD * toidx);
  2581.  
  2582.           Description    This  function  is  identical  to  msg_firstto (),
  2583.                          except  that  it  searches  for  the  last message
  2584.                          instead of the first.
  2585.  
  2586.           Return value   The RECORD  number  of  the  last  message  to the
  2587.                          specified user,  -1 if  not found or error. In the
  2588.                          latter   case   the   errortype   and  errorstring
  2589.                          variables are set.
  2590.  
  2591.           See also       msg_firstto (), msg_nextto (), msg_prevto ()
  2592.  
  2593.           Example        See msg_prevto ()
  2594.  
  2595.  
  2596.           ========================
  2597.           msg_prevto
  2598.           ========================
  2599.  
  2600.           Name           msg_prevto - find the previous message to the same
  2601.                          user as the one we just read was addressed to
  2602.  
  2603.           Usage          long msg_nextto (long recnr);
  2604.  
  2605.           Description    This message is identical to msg_nextto (), except
  2606.                          that it searches backwards.
  2607.  
  2608.           Return value   The RECORD  number of  the previous message to the
  2609.                          specified user, -1 if not found  or error.  In the
  2610.                          latter   case   the   errortype   and  errorstring
  2611.                          variables are set.
  2612.  
  2613.           See also       msg_firstto (), msg_lastto (), msg_nextto ()
  2614.  
  2615.           Example        #include "mb_lib.h"
  2616.                          long recnr;
  2617.  
  2618.                                                41
  2619.  
  2620.  
  2621.  
  2622.  
  2623.                          MSGTOIDX_RECORD toidx;
  2624.  
  2625.                          strcpy (toidx, "Frank Van.wensveen");
  2626.                          recnr = msg_lastto (toidx);
  2627.                          puts ("Mail waiting for you:");
  2628.                          puts ("Listed last to first")
  2629.                          while (recnr != -1) {
  2630.                            printf ("Message number: %d\n",
  2631.                                     msg_recnr2msgnr (recnr);
  2632.                            recnr = msg_prevto (recnr);
  2633.                          }
  2634.  
  2635.  
  2636.  
  2637.  
  2638.  
  2639.  
  2640.  
  2641.  
  2642.  
  2643.  
  2644.  
  2645.  
  2646.  
  2647.  
  2648.  
  2649.  
  2650.  
  2651.  
  2652.  
  2653.  
  2654.  
  2655.  
  2656.  
  2657.  
  2658.  
  2659.  
  2660.  
  2661.  
  2662.  
  2663.  
  2664.  
  2665.  
  2666.  
  2667.  
  2668.  
  2669.  
  2670.  
  2671.  
  2672.  
  2673.  
  2674.  
  2675.  
  2676.  
  2677.  
  2678.  
  2679.  
  2680.  
  2681.  
  2682.                                                42
  2683.  
  2684.  
  2685.  
  2686.  
  2687.           ============================================================
  2688.           11: NETMAIL (*.MSG) SERVICES
  2689.           ============================================================
  2690.           The following routines make up the  net_ family.  These functions
  2691.           are typically  used for  netmail support.  But in  fact any *.MSG
  2692.           base is supported, no  matter  what  type  of  mail  it contains.
  2693.           (Fmail for example uses *.MSG type files to store personal mail.)
  2694.  
  2695.           WARNING: though  the netmail  header defined in MB_LIB.H contains
  2696.           both a Zone and a Point field, these fields are  not supported by
  2697.           FSC-0001. Correct  interpretation of these fields by all software
  2698.           is NOT guaranteed. In fact, some  programs have  been verified to
  2699.           use  these  fields  for  other  data. FSC-0001 (sec) specified 2D
  2700.           addressing only.
  2701.           In order to use 4D addresses which will be processed correctly by
  2702.           all software,  it is  recommended that  you use the FMPT/TOPT and
  2703.           INTL kludges instead.
  2704.  
  2705.  
  2706.  
  2707.  
  2708.  
  2709.  
  2710.  
  2711.  
  2712.  
  2713.  
  2714.  
  2715.  
  2716.  
  2717.  
  2718.  
  2719.  
  2720.  
  2721.  
  2722.  
  2723.  
  2724.  
  2725.  
  2726.  
  2727.  
  2728.  
  2729.  
  2730.  
  2731.  
  2732.  
  2733.  
  2734.  
  2735.  
  2736.  
  2737.  
  2738.  
  2739.  
  2740.  
  2741.  
  2742.  
  2743.  
  2744.  
  2745.  
  2746.                                                43
  2747.  
  2748.  
  2749.  
  2750.  
  2751.           ========================
  2752.           net_first
  2753.           ========================
  2754.  
  2755.           Name           net_first -  get the  number of  the first netmail
  2756.                          message in a directory.
  2757.  
  2758.           Usage          int net_first (char * msgpath);
  2759.  
  2760.           Description    This  function  is  used  to get the number of the
  2761.                          first  message  in  a  *.MSG  (Opus-style) message
  2762.                          base. The  path to the directory holding the *.MSG
  2763.                          files is specified.
  2764.  
  2765.           Return value   The number of the first message  in the directory,
  2766.                          0 if  error or no messages found. In this case the
  2767.                          errortype and errorstring variables are set.
  2768.  
  2769.           Remarks        The specified  directory  is  supposed  to contain
  2770.                          *.MSG  files.  These  message  need not be netmail
  2771.                          messages.
  2772.  
  2773.           See also       net_last (), net_next (), net_prev ()
  2774.  
  2775.           Example        See net_next ()
  2776.  
  2777.  
  2778.           ========================
  2779.           net_next
  2780.           ========================
  2781.  
  2782.           Name           net_next - return the  number of  the message next
  2783.                          to the specified one.
  2784.  
  2785.           Usage          int net_next (char * msgpath, int nr);
  2786.  
  2787.           Description    While net_first  () return the number of the first
  2788.                          message in the specified  directory, this function
  2789.                          returns  the  number  of  the  message next to the
  2790.                          specified one. Typically you'd  call net_first (),
  2791.                          and  use  the  number  obtained  to  find the next
  2792.                          message until you run out of mail.
  2793.  
  2794.           Return value   The number of the message in the directory next to
  2795.                          the specified  number, 0  if error  or no messages
  2796.                          found. In this case the errortype  and errorstring
  2797.                          variables are set.
  2798.  
  2799.           See also       net_first (), net_last (), net_prev ()
  2800.  
  2801.           Example        #include "mb_lib.h"
  2802.                          int msgnum;
  2803.  
  2804.                          msgnum = net_first ("C:\\NETMAIL");
  2805.                          puts ("Netmail:");
  2806.                          while (msgnum != 0) {
  2807.                            printf ("%d\n", msgnum);
  2808.                            msgnum = net_next (msgnum);
  2809.  
  2810.                                                44
  2811.  
  2812.  
  2813.  
  2814.  
  2815.                          }
  2816.  
  2817.  
  2818.           ========================
  2819.           net_last
  2820.           ========================
  2821.  
  2822.           Name           net_last  -  get  the  number  of the last netmail
  2823.                          message in a directory.
  2824.  
  2825.           Usage          int net_last (char * msgpath);
  2826.  
  2827.           Description    This function is used to  get  the  number  of the
  2828.                          last  message  in  a  *.MSG  (Opus-style)  message
  2829.                          base. The path to the directory  holding the *.MSG
  2830.                          files is specified.
  2831.  
  2832.           Return value   The number  of the  last message in the directory,
  2833.                          0 if error or no messages found. In  this case the
  2834.                          errortype and errorstring variables are set.
  2835.  
  2836.           Remarks        The  specified  directory  is  supposed to contain
  2837.                          *.MSG files. These  message  need  not  be netmail
  2838.                          messages.
  2839.  
  2840.           See also       net_first (), net_next (), net_prev ()
  2841.  
  2842.           Example        See net_prev ()
  2843.  
  2844.  
  2845.           ========================
  2846.           net_prev
  2847.           ========================
  2848.  
  2849.           Name           net_prev  -  return  the  number  of  the  message
  2850.                          previous to the specified one.
  2851.  
  2852.           Usage          int net_prev (char * msgpath, int nr);
  2853.  
  2854.           Description    While net_last () returns  the number  of the last
  2855.                          message in  the specified directory, this function
  2856.                          returns the number of the message  previous to the
  2857.                          specified one.  Typically you'd  call net_last (),
  2858.                          and use the number  obtained to  find the previous
  2859.                          message until you run out of mail.
  2860.  
  2861.           Return value   The  number   of  the  message  in  the  directory
  2862.                          previous to  the specified  number, 0  if error or
  2863.                          no messages  found. In this case the errortype and
  2864.                          errorstring variables are set.
  2865.  
  2866.           See also       net_first (), net_last (), net_next ()
  2867.  
  2868.           Example        #include "mb_lib.h"
  2869.                          int msgnum;
  2870.  
  2871.                          msgnum = net_last ("C:\\NETMAIL");
  2872.                          puts ("Netmail listed backwards:");
  2873.  
  2874.                                                45
  2875.  
  2876.  
  2877.  
  2878.  
  2879.                          while (msgnum != 0) {
  2880.                            printf ("%d\n", msgnum);
  2881.                            msgnum = net_prev (msgnum);
  2882.                          }
  2883.  
  2884.  
  2885.           ========================
  2886.           net_hdr_clear
  2887.           ========================
  2888.  
  2889.           Name           net_hdr_clear -  clear  a  netmail  header record,
  2890.                          e.g. set all fields in the header to zero.
  2891.  
  2892.           Usage          void net_hdr_clear (NET_RECORD * hdr);
  2893.  
  2894.           Description    A netmail header record contains many fields, many
  2895.                          of which should be  set to  0 when  creating a new
  2896.                          message.  Because  the  fields in an uninitialized
  2897.                          header contain unknown values, we should initiali-
  2898.                          zed  each  field  before  using this header. Since
  2899.                          this is very cumbersome,  this  function  does the
  2900.                          job for you.
  2901.  
  2902.           Remarks        This  function   should  always   be  called  when
  2903.                          creating a new netmail header, otherwise unpredic-
  2904.                          table effects will occur.
  2905.  
  2906.           Example        #include "mb_lib.h"
  2907.  
  2908.                          NET_RECORD hdr;
  2909.  
  2910.                          net_hdr_clear (& hdr);
  2911.                          strcpy (hdr.who_from, "Frank Van.wensveen");
  2912.                          strcpy (hdr.who_to, "All");
  2913.                          strcpy (hdr.subject, "Test");
  2914.                          /* The header is now fully initialized! */
  2915.  
  2916.  
  2917.           ========================
  2918.           net_getlastread
  2919.           ========================
  2920.  
  2921.           Name           net_getlastread - get the lastread pointer for the
  2922.                          specified *.msg folder.
  2923.  
  2924.           Usage          int net_getlastread (char * msgpath);
  2925.  
  2926.           Description    To keep track of  what message  has been  read the
  2927.                          last time,  most message  readers /  editors use a
  2928.                          lastread pointer. This is a small  file located in
  2929.                          the message  directory, which  contains the number
  2930.                          of the message that was read last. 
  2931.                          This function is used to read the lastread pointer
  2932.                          for a specified message directory.
  2933.  
  2934.           Return value   The number of the message that was read last or -1
  2935.                          if an error  was  encountered.  In  that  case the
  2936.                          errortype and errorstring variables are set.
  2937.  
  2938.                                                46
  2939.  
  2940.  
  2941.  
  2942.  
  2943.  
  2944.           See also       net_setlastread ()
  2945.  
  2946.  
  2947.           ========================
  2948.           net_setlastread
  2949.           ========================
  2950.  
  2951.           Name           net_setlastread - set the lastread pointer for the
  2952.                          specified *.msg folder
  2953.  
  2954.           Usage          int setlastread (char * msgpath, int lastread);
  2955.  
  2956.           Description    This function is used to set  the lastread pointer
  2957.                          for the specified message directory to a specified
  2958.                          value.
  2959.  
  2960.           Return value   Zero  if  success,  non-zero   if  an   error  was
  2961.                          encountered.  In   this  case  the  errortype  and
  2962.                          errorstring variables are set.
  2963.  
  2964.           See also       net_getlastread
  2965.  
  2966.  
  2967.           ========================
  2968.           net_read_hdr
  2969.           ========================
  2970.  
  2971.           Name           net_read_hdr - read a netmail header
  2972.  
  2973.           Usage          int net_read_hdr (char * msgpath, int msgnr,
  2974.                                            NET_RECORD * hdr);
  2975.  
  2976.           Description    This function is much  like msg_read_hdr,  in that
  2977.                          it is used to read a message header.
  2978.  
  2979.           Return value   Zero  if   success,  non-zero   if  an  error  was
  2980.                          encountered.
  2981.  
  2982.           See also       msg_read_hdr (), net_read_text ()
  2983.  
  2984.           Example        See net_read_text ()
  2985.  
  2986.  
  2987.           ========================
  2988.           net_read_text
  2989.           ========================
  2990.  
  2991.           Name           net_read_text -  read the  text body  of a netmail
  2992.                          message.
  2993.  
  2994.           Usage          M_TEXT net_read_text (char * msgpath, int msgnum);
  2995.  
  2996.           Description    This function  is much like msg_read_text, in that
  2997.                          it is  used to  read the  text body  of a message.
  2998.                          Combined with the net_read_hdr () function, it can
  2999.                          be used for all  kinds of  netmail message reading
  3000.                          jobs. Because  text is returned by means of a text
  3001.  
  3002.                                                47
  3003.  
  3004.  
  3005.  
  3006.  
  3007.                          handle,  all  possibilities  with  regard  to text
  3008.                          manipulation apply.
  3009.  
  3010.           Return value   Text  handle,  NULL  on  error.  In  this case the
  3011.                          errortype and errorstring variables are set.
  3012.  
  3013.           See also       msg_read_text (), net_read_hdr ()
  3014.  
  3015.           Example        #include "mb_lib.h"
  3016.  
  3017.                          M_TEXT txt;
  3018.                          NET_RECORD hdr;
  3019.  
  3020.                          /* Reading message nr. 10        */
  3021.                          if (net_read_hdr ("C:\\NETMAIL", 10, & hdr))
  3022.                            exit (1);
  3023.                          txt = net_read_text ("C:\\NETMAIL, 10);
  3024.                          if (txt == NULL)
  3025.                            exit (1);
  3026.                          txt_dump (txt, printline, 70, NOKLUDGES);
  3027.  
  3028.  
  3029.           ========================
  3030.           net_write
  3031.           ========================
  3032.  
  3033.           Name           net_write - write a (netmail) message into a *.MSG
  3034.                          base.
  3035.  
  3036.           Usage          int net_write (char * msgpath, int msgnr,
  3037.                                         NET_RECORD * hdr, M_TEXT txt);
  3038.  
  3039.           Description    This  function  is  all  you need to write a *.MSG
  3040.                          message. Before calling the net_write () function,
  3041.                          you need  to determine the desired message number.
  3042.                          For new messages you  typically do  something like
  3043.                          msg_nr = net_last ("C:\\NETMAIL") + 1;.
  3044.                          You also  need to  create a message text, the text
  3045.                          handle of which  is  passed  to  the  net_write ()
  3046.                          function.
  3047.                          Unused fields in the message header must be set to
  3048.                          zero, or  unpredictable  results  will  occur. The
  3049.                          net_hdr_clear  ()  function  can be used for that.
  3050.                          The datetime field in the message  header does not
  3051.                          need to  be initialized, net_write () will do that
  3052.                          for you.
  3053.  
  3054.           Return value   Zero  on  success,  non-zero  when  an   error  is
  3055.                          encountered.  In   this  case  the  errortype  and
  3056.                          errorstring variables are set.
  3057.  
  3058.           See also       msg_write_new ();
  3059.  
  3060.           Example        #include "mb_lib.h"
  3061.                          NET_RECORD msghdr;
  3062.                          M_TEXT msgtxt;
  3063.  
  3064.                          /* Error checking left out to keep it short! */
  3065.  
  3066.                                                48
  3067.  
  3068.  
  3069.  
  3070.  
  3071.                          /* In other words, this is quick and dirty.  */
  3072.                          main () {
  3073.                            net_hdr_clear (& msghdr);
  3074.                            strcpy (msghdr.who_from, "Frank Van.wensveen");
  3075.                            strcpy (msghdr.who_to, "SysOp");
  3076.                            strcpy (msghdr.subject, "See how easy it is?");
  3077.                            msghdr.msg_attr = NM_LOCAL;
  3078.                            msgtxt = txt_new ("See? Writing a netmail is ");
  3079.                            txt_add (msgtxt, "easy! Even I could do it!\r");
  3080.                            net_write ("C:\\NETMAIL", 
  3081.                                        net_last ("C:\\NETMAIL") + 1, 
  3082.                                        & msghdr, msgtxt);
  3083.                          }
  3084.  
  3085.  
  3086.           ========================
  3087.           net_kill
  3088.           ========================
  3089.  
  3090.           Name           net_kill - kill a *.MSG message.
  3091.  
  3092.           Usage          int net_kill (char * msgpath, int msgnr);
  3093.  
  3094.           Description    This function is used  to kill  (delete) a message
  3095.                          in  a  *.MSG  base.  Unlike messages in the Hudson
  3096.                          message  base,  *.MSG   messages   are  physically
  3097.                          deleted when killed.
  3098.  
  3099.           Return value   Zero  on   success,  non-zero   if  an  error  was
  3100.                          encountered.  In  this  case   the  errortype  and
  3101.                          errorstring variables are set.
  3102.  
  3103.  
  3104.           ========================
  3105.           net_fixup4d
  3106.           ========================
  3107.  
  3108.           Name           net_fixup4d - convert the zone and point fields in
  3109.                          a *.MSG netmail  header  into  INTL  and FMPT/TOPT
  3110.                          kludges   to   overcome  the  FSC-0001  compliance
  3111.                          problem.
  3112.  
  3113.           Usage          int net_fixup4d (NET_RECORD * hdr, M_TEXT txt);
  3114.  
  3115.           Description    See  msg_fixup4d.  The  difference  between Hudson
  3116.                          netmail  headers  and  *.MSG  headers  is that the
  3117.                          latter also contain unsupported  point fields. The
  3118.                          Hudson  netmail  header  does  not  support  point
  3119.                          addresses.
  3120.  
  3121.           Return value   Zero on success, non-zero on error.
  3122.  
  3123.           Remarks        CAUTION:  The  fixup  functions  add  text  to the
  3124.                          specified  text  handle.  The  text  handle *MUST*
  3125.                          therefore be initialized, otherwise "unpredictable
  3126.                          results"  (an   euphemism  for  a  total  screwup,
  3127.                          usually)  will  occur.  You   *must*  have  called
  3128.  
  3129.  
  3130.                                                49
  3131.  
  3132.  
  3133.  
  3134.  
  3135.                          txt_new ()  previous to  calling msg_fixup4d () or
  3136.                          net_fixup4d ().
  3137.  
  3138.           See also       msg_fixup4d ()
  3139.  
  3140.           Example        see msg_fixup4d (). 
  3141.  
  3142.  
  3143.  
  3144.  
  3145.  
  3146.  
  3147.  
  3148.  
  3149.  
  3150.  
  3151.  
  3152.  
  3153.  
  3154.  
  3155.  
  3156.  
  3157.  
  3158.  
  3159.  
  3160.  
  3161.  
  3162.  
  3163.  
  3164.  
  3165.  
  3166.  
  3167.  
  3168.  
  3169.  
  3170.  
  3171.  
  3172.  
  3173.  
  3174.  
  3175.  
  3176.  
  3177.  
  3178.  
  3179.  
  3180.  
  3181.  
  3182.  
  3183.  
  3184.  
  3185.  
  3186.  
  3187.  
  3188.  
  3189.  
  3190.  
  3191.  
  3192.  
  3193.  
  3194.                                                50
  3195.  
  3196.  
  3197.  
  3198.  
  3199.  
  3200.  
  3201.  
  3202.  
  3203.                          This page intentionally left blank.
  3204.  
  3205.  
  3206.  
  3207.  
  3208.  
  3209.  
  3210.  
  3211.  
  3212.  
  3213.  
  3214.  
  3215.  
  3216.  
  3217.  
  3218.  
  3219.  
  3220.  
  3221.  
  3222.  
  3223.  
  3224.  
  3225.  
  3226.  
  3227.  
  3228.  
  3229.  
  3230.  
  3231.  
  3232.  
  3233.  
  3234.  
  3235.  
  3236.  
  3237.  
  3238.  
  3239.  
  3240.  
  3241.  
  3242.  
  3243.  
  3244.  
  3245.  
  3246.  
  3247.  
  3248.  
  3249.  
  3250.  
  3251.  
  3252.  
  3253.  
  3254.  
  3255.  
  3256.  
  3257.  
  3258.                                                51
  3259.